判斷一個變量是否是空對象 {}

判斷一個變量是否是空對象有兩步javascript

  1. 變量是否是對象
  2. 對象是否是空的

判斷變量是否是對象

var obj;
// 初級版本
typeof obj === 'object'

複製代碼

null

typeof 便可作一個簡單的判斷,可是要注意 null 由於typeof null === 'object' 爲 truejava

因此判斷是否是對象的語句以下數組

obj !== null && typeof obj === 'object'
複製代碼

[]

由於 typeof [] === 'object'函數

Array.isArray(obj) 判斷ui

因此判斷是否是對象的終極語句以下spa

obj !== null && typeof obj === 'object' && !Array.isArray(obj)
複製代碼

效果以下prototype

Object.prototype.toString.call

評論區大佬用一個比較簡單的辦法解決了判斷是否是對象的問題3d

socode

Object.prototype.toString.call(obj) === '[object Object]'
複製代碼

判斷對象是否是空對象

通過上面對象的判斷以後,肯定是對象的前提下,怎麼肯定這個對象是一個空對象呢?cdn

Object.keys

它會先列舉對象的全部可枚舉屬性鍵名到數組中,再判斷數組的長度 Object.keys(obj).length === 0 對不可枚舉的屬性無效

JSON.stringify

JSON.stringify(obj) === {} 其沒法轉化函數鍵值對,同時對不可枚舉的屬性一籌莫展

Object.getOwnPropertyNames

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

能夠獲取到不可枚舉的屬性鍵,正解!!!

還要注意一種狀況對象屬性爲 Symbol 的時候,Object.getOwnPropertyNames 沒法檢測出來,須要單獨處理

當一個 symbol 類型的值在屬性賦值語句中被用做標識符,該屬性(像這個 symbol 同樣)是匿名的;而且是不可枚舉的。由於這個屬性是不可枚舉的,它不會在循環結構 「for( ... in ...)」 中做爲成員出現,也由於這個屬性是匿名的,它一樣不會出如今 「Object.getOwnPropertyNames()」 的返回數組裏。這個屬性能夠經過建立時的原始 symbol 值訪問到,或者經過遍歷 「Object.getOwnPropertySymbols()」 返回的數組。

因此要加上 Symbol 判斷

Object.getOwnPropertySymbols(obj).length === 0
複製代碼

Reflect.ownKeys

經評論區高人指點,發現 Reflect.ownKeys 既能夠解決非枚舉屬性也能夠解決Symbol屬性。

總結

終極版判斷一個變量是否是空對象的代碼

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)

複製代碼

封裝成函數以下

function isEmptyObj(obj) {
    return obj !== 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)
}


複製代碼

相關文章
相關標籤/搜索