枚举性:属性是否会出现在对象的属性枚举中。存在性:对象中是否存在这个属性
从名字上看,首先这个对象要存在这个对象上,才能考虑是否可枚举,也就是存在性>枚举型。
想一下以下代码的结果:
var myObject = {
a:undefined
}
console.log(myObject.a); //?
console.log(myObject.b); //?
相信你已经有了答案,两个属性值都是undefined
,但是会有人问,对象属性的存在性和枚举性,应该是对象属性,没道理讲属性值?
myObject.a
和myObject.b
都为undefined
。区别是:a作为对象属性存在,属性值是undefined
,但因为没有在对象上找到b的同名属性,甚至可能原型链上也不存在,返回了undefined
。那么我们区分这两种情况呢?也就是 我们如何判断对象上是否存在某个属性。
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]]原型链
in操作符
的特殊性:
- 对于数组,检测属性名是否存在
- 对于数组,检测数组的下标/索引
刚才我们使用了遍历如for...in
、Object.getOwnPropertyNames
、Object.keys()
,尝试列出对象上的所有属性,那么他们有什么区别呢?我们改造下以上的代码:
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,但就是没有遍历出来。这个与当前属性的属性描述符中定义的 ennmerable
有关。
在定义对象时,对象上的属性默认都是可见的,即ennmerable:true
,如果想屏蔽特殊的属性,可以修改为false
。
Object.keys() & Object.getOwnPropertyNames(…)相同点:都只查找对象直接含有的属性,不会去其原型链[[Prototype]]上寻找
不同点:Object.keys() 会遍历所有可枚举的属性
Object.getOwnPropertyNames(…) 会遍历所有的对象属性
for…in 用来遍历对象上以及其原型链上的可枚举属性。
通过以上分析,我们可以在判断对象属性时更加清晰些。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。