There are two steps to determining whether a variable is an empty object

  1. Is a variable an object
  2. Is the object empty

Determine if a variable is an object

var obj;
// Initial version
typeof obj === 'object'

Copy the code

null

Typeof does a simple check, but beware of null because typeof null === ‘object’ is true

So the statement to determine whether it is an object is as follows

obj ! = =null && typeof obj === 'object'
Copy the code

[]

Because typeof [] === ‘object’

Use Array. IsArray (obj) judgment

So the ultimate statement for determining whether an object is an object is as follows

obj ! = =null && typeof obj === 'object'&&!Array.isArray(obj)
Copy the code

Results the following

Object.prototype.toString.call

The comment section boss solved the problem of deciding whether to be an object in a relatively simple way

so

Object.prototype.toString.call(obj) === '[object Object]'
Copy the code

Determines whether an object is empty

After judging the above object, how to determine that the object is an empty object if it is determined to be an object?

Object.keys

Keys (obj). Length === 0 is not valid for non-enumerable attributes

JSON.stringify

Json.stringify (obj) === {} it cannot convert function key-value pairs and does nothing about non-enumerable attributes

Object.getOwnPropertyNames

Object.getOwnPropertyNames(obj).length === 0

You can get property keys that are not enumerable.

Note also that a situation in which the Object properties for the Symbol, Object. GetOwnPropertyNames cannot detect, require a separate treatment

When a value of type symbol is used as an identifier in an attribute assignment statement, the attribute (like this Symbol) is anonymous; And is not enumerable. Because this attribute is not enumerable, it does not exist in the loop structure “for(… in …) “In appear as members, but also because of this property is anonymous, it won’t appear in the same” Object. GetOwnPropertyNames () “in the returned array. This property can be created when the original symbol of access to the value, or by traversal “Object. GetOwnPropertySymbols ()” the returned array.

So we have to add Symbol to it

Object.getOwnPropertySymbols(obj).length === 0
Copy the code

Reflect.ownKeys

Reflecting. OwnKeys can handle both non-enumerated and Symbol attributes.

conclusion

The ultimate version determines whether a variable is an empty object

obj ! = =null
&& typeof obj === 'object'&&!Array.isArray(obj)
&& (Object.getOwnPropertyNames(obj).length === 0)
&& (Object.getOwnPropertySymbols(obj).length === 0)

// or
(Object.prototype.toString.call(obj) === '[object Object]')
&& (Object.getOwnPropertyNames(obj).length === 0)
&& (Object.getOwnPropertySymbols(obj).length === 0)

// or
(String(obj) === '[object Object]') && (Reflect.ownKeys(obj).length === 0)

Copy the code

The function is encapsulated as follows

function isEmptyObj(obj) {
    returnobj ! = =null
    && typeof obj === 'object'&&!Array.isArray(obj)
    && (Object.getOwnPropertyNames(obj).length === 0)
    && (Object.getOwnPropertySymbols(obj).length === 0)}// or
function isEmptyObj(obj) {
    return (Object.prototype.toString.call(obj) === '[object Object]')
    && (Object.getOwnPropertyNames(obj).length === 0)
    && (Object.getOwnPropertySymbols(obj).length === 0)}// or
function isEmptyObj(obj) {
    return (String(obj) === '[object Object]') && (Reflect.ownKeys(obj).length === 0)}Copy the code