不可枚举属性
for in函数会遍历对象中的所有可枚举属性,那么,问题来了,不可枚举属性又是什么?
每个对象的属性自身,都有一个属性,enumerable,若属性A的属性值即A.enumerable为false,则属性A为不可枚举属性。
为何要定义enumerable属性呢?就是为了一下三个操作。enumerable属性值为false的属性,在以下三个操作中不会被取到:
- for…in循环
- Object.keys方法
- JSON.stringify方法
如何定义一个属性的enumerable属性值呢,举个例子,下面这段代码,便是为对象obj定义了一个名为d的属性,而a.enumerable的属性值为false,即d为不可枚举属性。
Object.defineProperty(obj, 'a', {
value: 1,
enumerable: false
});
捣乱的prototype
我们以为这样就好啦,可是若之前有人,为prototype加上了一些属性,比如说,现在有这样一个数组,arr[1,2,3],而数组arr的prototype之前又被某个人增加了属性,arr.prototype.someAttr="i am some attribute of prototype",这样,如果我们通过for in遍历数组,得到的不只是1,2,3,还有someAttr:i am some attribute of prototype.
悲剧了吧,虽然prototype为不可枚举属性,但其含有的属性仍然被遍历了。这样的情况,我们可以通过以下代码的处理,来避免。
for(var i in arr){
if(array.hasOwnProperty(i)) {
console.log(i+":"+array[i]);
}
}
该段代码中,hasOwnProperty函数的作用,就是“判断一个对象是否有你给出名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。”
这样,我们得到的输出结果便是0:1 1:2 2:3