判斷屬性存在或者遍歷屬性是平常開發中常常會用到。只是針對這些操做符、語句、方法,有些混淆。因此總結一下。javascript
對象屬性目前只能是字符串值或者 symbol 值html
A property key value is either an ECMAScript String value or a Symbol valuejava
明確了這個規則後,開始下面的說明。web
翻譯爲屬性的屬性?這個概念我也有點說不清,看看下面的參考數組
Property Attributes
有 Value、Writable、Enumerable、Configurable。這個能夠經過 Object.getOwnPropertyDescriptor
獲取值。經過 Object.defineProperty
進行定義或者修改。oop
另外還有 Get、Setthis
本文的重點是討論 Enumerable
,這個值設置爲 false 後,屬性是不可遍歷的。spa
可是不可遍歷了,我仍是須要獲取這個屬性該怎麼辦?
指定的屬性在指定的對象或其原型鏈中,則in 運算符返回true
Reflect.has
和 in
的效果相同
這裏的重點是 in
會檢查原型鏈
console.log(length in []); // true // 繼承的 Symbol console.log(Symbol.iterator in []); // true // 繼承的方法 console.log('toString' in []); // true 複製代碼
for...in
循環只遍歷可枚舉屬性(包括它的原型鏈上的可枚舉屬性)
所以 for...in
的行爲受到 Enumerable
的控制
for in 區別 // 遍歷除了 symbol 之外的可枚舉
屬性
let obj = { [Symbol('my_key')]: 1, enum: 2, nonEnum: 3 }; Object.defineProperty(obj, 'nonEnum', { enumerable: false }); console.log(Object.keys(obj)) let obj2 = Object.create(obj) obj2.myVal = 5 console.log(obj2); // { myVal: 5 } for (var prop in obj2) { console.log('obj2 prop: ', prop); // myVal, enum } 複製代碼
會返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致 。
// 省略上面的代碼 Object.keys(obj) // ['enum'] Object.keys(obj2) // ['myVal'] 複製代碼
返回一個由指定對象的全部自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值做爲名稱的屬性)組成的數組。
// 省略上面的代碼 Object.getOwnPropertyNames(obj) // ['enum', 'nonEnum'] 複製代碼
Object.prototype.hasOwnProperty
用來判斷對象自身屬性。
一個經常使用的判斷:遍歷一個對象的全部自身屬性
var buz = { fog: 'stack' }; for (var name in buz) { if (buz.hasOwnProperty(name)) { console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]); } else { console.log(name); // toString or something else } } 複製代碼
返回一個給定對象自身的全部 Symbol 屬性的數組
// 省略上面的代碼 Object.getOwnPropertySymbols(obj) // [ Symbol(my_key) ] 複製代碼
上面的方法操做符,饒了一圈。和 Enumerable
Symbol
的有無打交道。
有沒有方法可以拿到全部的屬性 (我全都要.webp)
答案就是: Reflect.ownKeys
// 省略上面的代碼 Reflect.ownKeys(obj) // [ Symbol(my_key), 'enum', 'nonEnum' ] 複製代碼
對象屬性目前只能是字符串值或者 symbol 值。因此下面的狀況會出現 toPrimitive
或者 toString
的轉換
let obj3 = { [obj]: 33 } // { '[object Object]': 33 } 複製代碼
固然須要使用對象做爲 key, 須要用到 Map
了,這些是後話。
通常狀況下都是用 Object.keys
來遍歷自身可枚舉屬性。Object.keys
是 ES5 的標準。
之前 ES3 的時候是須要 in
操做符 和 hasOwnProperty
配合使用
全都要的狀況: Reflect.ownKeys
要考慮 Enumerable
爲 false 時, 用 Object.getOwnPropertyNames
要考慮 Symbol
時, 用 Object.getOwnPropertySymbols
in - JavaScript | MDN Keys in Javascript objects can only be strings? - Stack Overflow