判斷一個變量是否是空對象有兩步javascript
var obj;
// 初級版本
typeof obj === 'object'
複製代碼
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
評論區大佬用一個比較簡單的辦法解決了判斷是否是對象的問題3d
socode
Object.prototype.toString.call(obj) === '[object Object]'
複製代碼
通過上面對象的判斷以後,肯定是對象的前提下,怎麼肯定這個對象是一個空對象呢?cdn
它會先列舉對象的全部可枚舉屬性鍵名到數組中,再判斷數組的長度 Object.keys(obj).length === 0
對不可枚舉的屬性無效
JSON.stringify(obj) === {}
其沒法轉化函數鍵值對,同時對不可枚舉的屬性一籌莫展
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
既能夠解決非枚舉屬性也能夠解決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)
}
複製代碼