有很多关于如何将indexOf实现转换为Array原型的解决方案,以便它可以在Internet Explorer下运行,但是我偶然发现了一个似乎无法在我看到的任何地方解决的问题
使用非常好的implementation at MDC同意,我现在有以下代码存在问题:
// indexOf support for IE (from MDC)
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this && this[from] === elt)
return from;
}
return -1;
};
}
var i = [1,2,3,4];
for (j in i)
{
alert(i[j]);
}
我希望收到4个警报,每个警报包含一个数组元素。 在Firefox和Chrome中,这正是我所看到的,但是在IE8中,我得到一个包含indexOf功能代码的附加警报。
可以做些什么来避免这种情况?
答案 0 :(得分:5)
这是因为在IE中,由于该方法不存在,因此它被添加到Array.prototype
,并且它仍然是可枚举的。
对于使用Arrays进行woking(通常是任何类似数组的对象),我不建议使用for...in
语句。
为什么?
for...in
语句旨在枚举对象属性。for...in
语句会抓取原型链。最简单的方法,简单的for
循环:
for (var j = 0; j < i.length; j++) {
alert(i[j]);
}
另见:
答案 1 :(得分:3)
这是因为您编辑了Array.prototype,因此创建的任何数组都继承了“in”命令可以看到的自定义VISIBLE方法indexOf
。
for..in
构造不像PHP的foreach那样 - 它不仅迭代数组中的所有项,而且还迭代数组OBJECT可能具有的所有方法和属性(JavaScript中的数组)实际上是“伪装”的对象)。本地方法对于for..in
构造是不可见的,但所有自定义添加都不是。
在您的示例中,任何数组都如下所示:
Array:
- [0] value
- [1] value
- [2] value
- ..
- [N] value
- [IndexOf] value
要避免使用非需要的继承方法和属性,可以使用方法hasOwnProperty()
:
for (j in j){
if(i.hasOwnProperty(j){
alert(i[j])
}
}
hasOwnProperty
检查密钥是否未被继承并属于实际对象。这样只会传递所需的值。
答案 2 :(得分:0)
您可以尝试添加:
for (j in i) {
if (i.hasOwnProperty(j)) {
alert(j);
}
}