在 IE8 中发布扩展数组
Issue extending Array in IE8
所以 IE8 不支持 Array.indexOf()
,所以我复制了一些扩展 Array 原型的代码,以便它受支持并且可以正常工作。
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;
};
}
但是,当我现在遍历数组时,我 运行 遇到了问题。以此为例:
arrayObject = [];
//do some stuff
for(var i in arrayObject) {
...
}
问题是在扩展 Array 原型之后,上面 i
的值之一现在等于 indexOf
,并且该索引处的值(即 arrayObj[i]
)等于函数的内容。即使数组的长度为零,也会发生这种情况!!因此,即使数组为空,它仍然会为 indexOf
条目迭代一次。
我意识到我可以简单地在循环中进行一些类型检查,但我宁愿不这样做,因为我正在对一个大型现有项目进行回退兼容性改造。有没有办法在没有 运行 的情况下在 IE8 中使用 indexOf
数组功能?
您可以使用 hasOwnProperty 来确保 i 是数组的索引而不是像 indexOf 这样的函数。
for (var i in arrayObject) {
if( arrayObject.hasOwnProperty( i ) ) {
//...
}
}
有关详细信息,请参阅下面的文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
也就是说我可能会推荐使用计数器,例如
for(var i = 0; i < arrayObject.length; i++) {}
或来自下划线、dojo 或 jquery 等框架的 each 方法,而不是像这样使用 for..in 循环。
如果有的话,你只需要使用for..in
来迭代数组,只需检查当前项是否在Array对象中定义,Object.hasOwnProperty
,像这样
var arrayObject = [];
for(var i in arrayObject) {
if (arrayObject.hasOwnProperty(i)) {
...
}
}
注意:根据MSDN's documentation of hasOwnProperty
,它在 Internet Explorer 8 标准模式下受支持。
定义 indexOf
的正确方法是使不可枚举,像这样
Object.defineProperty(Array.prototype, 'indexOf', {
enumerable: false,
configurable: false,
writable: false,
value: function polyFillIndexOf() {...}
});
由于我们定义为不可枚举,for..in
循环,不会挑indexOf
属性。因此,您仍然可以将 for..in
与 Array 对象一起使用(尽管不建议这样做)。
但不幸的是,根据 MSDN's documentation of Object.defineProperty
,它仅适用于 IE-8 中的 DOM 个对象。
除此之外,当您将 for..in
与数组一起使用时,您可能 运行 进入此 inconsistent order of keys problem mentioned in MDN,
Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that for...in
will return the indexes in any particular order and it will return all enumerable properties, including those with non–integer names and those that are inherited.
Because the order of iteration is implementation dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for loop with a numeric index (or Array.prototype.forEach()
or the for...of
loop) when iterating over arrays where the order of access is important.
因此,最简单也是最好的方法是使用简单的 for
循环,使用数字数组索引,就像这样
for(var i = 0; i < arrayObject.length; i++) {
console.log(arrayObject[i]);
}
或使用Array.prototype.forEach
(Internet Explorer 8 标准模式也支持),像这样
arrayObject.forEach(function(currentItem) {
...
});
PS:小心
arrayObject = [];
您实际上是在创建一个名为 arrayObject
的全局变量。您可能想使用 var
关键字,例如
var arrayObject = [];
所以 IE8 不支持 Array.indexOf()
,所以我复制了一些扩展 Array 原型的代码,以便它受支持并且可以正常工作。
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;
};
}
但是,当我现在遍历数组时,我 运行 遇到了问题。以此为例:
arrayObject = [];
//do some stuff
for(var i in arrayObject) {
...
}
问题是在扩展 Array 原型之后,上面 i
的值之一现在等于 indexOf
,并且该索引处的值(即 arrayObj[i]
)等于函数的内容。即使数组的长度为零,也会发生这种情况!!因此,即使数组为空,它仍然会为 indexOf
条目迭代一次。
我意识到我可以简单地在循环中进行一些类型检查,但我宁愿不这样做,因为我正在对一个大型现有项目进行回退兼容性改造。有没有办法在没有 运行 的情况下在 IE8 中使用 indexOf
数组功能?
您可以使用 hasOwnProperty 来确保 i 是数组的索引而不是像 indexOf 这样的函数。
for (var i in arrayObject) {
if( arrayObject.hasOwnProperty( i ) ) {
//...
}
}
有关详细信息,请参阅下面的文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
也就是说我可能会推荐使用计数器,例如
for(var i = 0; i < arrayObject.length; i++) {}
或来自下划线、dojo 或 jquery 等框架的 each 方法,而不是像这样使用 for..in 循环。
如果有的话,你只需要使用for..in
来迭代数组,只需检查当前项是否在Array对象中定义,Object.hasOwnProperty
,像这样
var arrayObject = [];
for(var i in arrayObject) {
if (arrayObject.hasOwnProperty(i)) {
...
}
}
注意:根据MSDN's documentation of hasOwnProperty
,它在 Internet Explorer 8 标准模式下受支持。
定义 indexOf
的正确方法是使不可枚举,像这样
Object.defineProperty(Array.prototype, 'indexOf', {
enumerable: false,
configurable: false,
writable: false,
value: function polyFillIndexOf() {...}
});
由于我们定义为不可枚举,for..in
循环,不会挑indexOf
属性。因此,您仍然可以将 for..in
与 Array 对象一起使用(尽管不建议这样做)。
但不幸的是,根据 MSDN's documentation of Object.defineProperty
,它仅适用于 IE-8 中的 DOM 个对象。
除此之外,当您将 for..in
与数组一起使用时,您可能 运行 进入此 inconsistent order of keys problem mentioned in MDN,
Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that
for...in
will return the indexes in any particular order and it will return all enumerable properties, including those with non–integer names and those that are inherited.Because the order of iteration is implementation dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for loop with a numeric index (or
Array.prototype.forEach()
or thefor...of
loop) when iterating over arrays where the order of access is important.
因此,最简单也是最好的方法是使用简单的 for
循环,使用数字数组索引,就像这样
for(var i = 0; i < arrayObject.length; i++) {
console.log(arrayObject[i]);
}
或使用Array.prototype.forEach
(Internet Explorer 8 标准模式也支持),像这样
arrayObject.forEach(function(currentItem) {
...
});
PS:小心
arrayObject = [];
您实际上是在创建一个名为 arrayObject
的全局变量。您可能想使用 var
关键字,例如
var arrayObject = [];