枚舉性:屬性是否會出現(xiàn)在對象的屬性枚舉中。
存在性:對象中是否存在這個屬性
從名字上看,首先這個對象要存在這個對象上,才能考慮是否可枚舉,也就是存在性>枚舉型。
想一下以下代碼的結(jié)果:
var myObject = {
a:undefined
}
console.log(myObject.a); //?
console.log(myObject.b); //?
相信你已經(jīng)有了答案,兩個屬性值都是undefined,但是會有人問,對象屬性的存在性和枚舉性,應(yīng)該是對象屬性,沒道理講屬性值?
myObject.a和myObject.b都為undefined。區(qū)別是:a作為對象屬性存在,屬性值是undefined,但因為沒有在對象上找到b的同名屬性,甚至可能原型鏈上也不存在,返回了undefined。那么我們區(qū)分這兩種情況呢?也就是 我們?nèi)绾闻袛鄬ο笊鲜欠翊嬖谀硞€屬性。
var myObject ={
a:2
};
console.log( 'a' in myObject);// true
console.log( 'b' in myObject);// false
console.log(myObject.hasOwnProperty('a'));//true
console.log(myObject.hasOwnProperty('b'));//false
for(var prop in myObject){
if(prop==='a') console.log(true;)
} //true
Object.getOwnPropertyNames(myObject);//['a']
Object.keys();//['a']
in操作符 用來檢測屬性是否存在于對象以及其[[Prototype]]原型鏈中。
obj.hasOwnProperty(…)用來檢測屬性是否存在于對象上,不會檢查其[[Prototype]]原型鏈
:raising_hand:
in操作符的特殊性:
對于數(shù)組,檢測屬性名是否存在
對于數(shù)組,檢測數(shù)組的下標(biāo)/索引
剛才我們使用了遍歷如for...in、Object.getOwnPropertyNames、Object.keys(),嘗試列出對象上的所有屬性,那么他們有什么區(qū)別呢?我們改造下以上的代碼:
var myObject = {
a:2
}
Object.defineProperty(myObject,"a",{
enumerable:false
})
Object.defineProperty(myObject,"b",{
enumerable:true,
value:2
})
//----------------
for(var prop in myObject){
console.log(prop,myObject[prop]);
} //b 2
Object.getOwnPropertyNames(myObject);//['a','b']
Object.keys(myObject);//['b']
可以看到,myObject中確確實實存在了屬性a,但就是沒有遍歷出來。這個與當(dāng)前屬性的屬性描述符中定義的 ennmerable有關(guān)。
在定義對象時,對象上的屬性默認(rèn)都是可見的,即ennmerable:true,如果想屏蔽特殊的屬性,可以修改為false。
Object.keys() & Object.getOwnPropertyNames(…)
相同點:都只查找對象直接含有的屬性,不會去其原型鏈[[Prototype]]上尋找
不同點:Object.keys() 會遍歷所有可枚舉的屬性
? Object.getOwnPropertyNames(…) 會遍歷所有的對象屬性
for…in 用來遍歷對象上以及其原型鏈上的可枚舉屬性。
通過以上分析,我們可以在判斷對象屬性時更加清晰些。