Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ways to determine if something is a plain object in JavaScript

I've recently stumbled on this function which determines if something is a plain object is JavaScript:

function isPlainObject (value){
  if (typeof value !== 'object' || value === null) return false;

  let proto = value;
  while (Object.getPrototypeOf(proto) !== null) {
    proto = Object.getPrototypeOf(proto);
  }

  return Object.getPrototypeOf(value) === proto;
};

Source: https://github.com/redux-utilities/redux-actions/blob/master/src/utils/isPlainObject.js

I would like to know:

  1. If the following approach will do exactly the same stuff?
  2. If so, can it be considered more effective?
function isPlainObj(value){
  if (typeof value !== 'object' || value === null) return false;
  let obj = {};
  return Object.getPrototypeOf(value) === Object.getPrototypeOf(obj)
}
like image 570
tykatyk Avatar asked Dec 05 '25 21:12

tykatyk


2 Answers

Checking if a value is a plain object:

/*
 isPlainObject({}) // true
 isPlainObject() // false
 isPlainObject(null) // false
 isPlainObject(true) // false
 isPlainObject('1') // false
 isPlainObject([]) // false
 isPlainObject(new Function()) // false
 isPlainObject(new Date()) // false
 */
const isPlainObject = value => value?.constructor === Object;

Excludes nulls, scalars, arrays, functions and any extended type other than Object.

like image 131
Javier Rey Avatar answered Dec 08 '25 10:12

Javier Rey


Either the method provided in the OP question or @Javier Rey's answer, both of them do not work well in some cases. The Atomics, the object with Symbol.iterator or Symbol.toStringTag static data properties, and JSON namespace object

The following test cases will fail:

const iterable1 = {};

iterable1[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};

isPlainObject(iterable1) // true, should be false
isPlainObject(JSON) // true, should be false

So we need to do extra checks for these objects.

export default function isPlainObject(value) {
    if (typeof value !== 'object' || value === null) {
        return false;
    }

    const prototype = Object.getPrototypeOf(value);
    return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
} 
like image 26
slideshowp2 Avatar answered Dec 08 '25 12:12

slideshowp2



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!