2012-06-20 42 views
2

所以有此功能为什么在迭代中会出现原型函数?

Array.prototype.containsCaseInsensitive = function(obj) { 
    var i = this.length; 
    while (i--) { 
    if (this[i].toUpperCase() === obj.toUpperCase()) { 
     return true; 
    } 
    } 
    return false; 
} 

然后我创建这个数组:

ary = [0,1,2,3]; 
for (item in ary){ 
    console.log(ary[item]) 
} 

输出如下:

0 
1 
2 
3 
function(obj) { 
    var i = this.length; 
    while (i--) { 
     if (this[i].toUpperCase() === obj.toUpperCase()) { 
      return true; 
     } 
    } 
    return false; 
} 

为什么在迭代的功能? 谢谢!

回答

4

你的属性是可枚举的(尽管你不应该枚举使用for ... in ...的数组的键)。

在ES5兼容的浏览器,你可以安全地添加功能使用Object.defineProperty一个不可枚举的属性:

Object.defineProperty(Array.prototype, 'containsCaseInsensitive', { 
    value: function() { 
     ... 
    } 
}); 
+0

唯一的问题是版本是1.8.5,所以降低浏览器的兼容性。在某些情况下,我认为更好地过滤元素。 – Gustavo

0

当您使用for .. in该数组被视为一个对象,这就是为什么它会显示所有的属性。经常使用以达到您想要的效果。

0

因为containsCaseInsensitive是您的数组的成员,并且您遍历数组的所有成员。您不应该编写for ... in迭代来迭代数组中的项目。

0

因为for..in会输出对象的所有可枚举属性。

如果要在阵列的唯一值,你可以使用:

for (item in ary){ 
    if (ary.hasOwnProperty(item)) 
     console.log(ary[item]) 
} 

在支持的环境,你也可以使用defineProperty设定的功能为不可枚举的,像这样:

Object.defineProperty(Array.prototype, 'containsCaseSensitive', { 
    value: function(obj) {}, 
    enumerable: false 
    //^this is default when you use defineProperty, so you don't need it 
    // but it is to show you how that works :-) 
}); 

但是,通常不建议将for..in用于数组,因此您只能将其用于字面值对象。

对于数组,建议使用:

for (var i = 0, l = arr.length; i < l; i++) { 
    console.log(arr[ i ]); 
} 

或者,如果支持的话:

arr.forEach(function(el) { 
    console.log(el); 
}); 
+0

我认为“如果支持”条款,使'.forEach'比'实践更是雪上加霜。当涉及到JavaScript时。 'hasOwnProperty'检查适用于特定示例,因为该属性是在Array对象的定义的,但它不涉及'var x = [1,2];等问题。 x.prop ='a';' –

+0

为什么你认为这会让情况变得更糟?如果你只支持现代浏览器,你一定要使用'forEach',这很棒并且可以做所有事情。在node.js中,如果你不使用它,我会咬你。 –

+0

@DavidHedlund我不同意。 '.forEach'现在是_expected_ practice,您应该使用shim将其添加到本机不支持的浏览器中。在正确编写的ES5代码中,'.hasOwnProperty'几乎是不需要的。 – Alnitak

相关问题