有这样一个问题
有一天,业务上有个场景需要用到数组的indexOf方法,本来高高兴兴的用了,结果呢,IE8不兼容
怎么解决呢,我写了如下兼容代码
Array.prototype.indexOf = function(item) {
for (var i = 0; i < this.length; i++) {
if (this[i] == item)
return i;
}
return -1;
}
很简单嘛,然后放在了全局公用的js文件里,避免大家再考虑兼容性问题
然而问题出现了,业务中有不少使用for in遍历数组的,最后发现
var data = [1,2,3];
for (var i in data) {
console.log(data[i]);
}
输出了1,2,3,function ……
难道原型上的indexOf方法也会被遍历到?
但是Array.prototype其他的方法(slice、join、splice……)以及Array.prototype对象的原型Object.prototype上的那么多方法没有遍历呢
查了一些资料终于弄清楚了,原来对象的属性还有可枚举和不可枚举之分,每个对象的属性都有一个属性标识enumeralbe
哪些是不可枚举?
1、基本数据类型原型上的方法不可枚举
2、指定enumeralbe为false的属性不可枚举
ps: 我们添加的对象属性在不指定enumeralbe时其enumeralbe都为true
以下对比两种写法的差别
// IE8实现了defineProperty,但是仅用于DOM对象,在IE8下会报错
Object.defineProperty(Array.prototype,'haha', {
enumerable: false,
value: 1
});
Array.prototype.haha = 1;
var data = [1,2,3];
for (var i in data) {
console.log(data[i]);
}
可枚举类型
很显然,非不可枚举类型的属性都是可枚举类型的,即enumeralbe为true的
网友评论