我一直在项目的主JavaScript文件中添加一个Array.indexOf() polyfill。我从devdocs.io上拿来的:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement , fromIndex) {
var i,
pivot = (fromIndex) ? fromIndex : 0,
length;
if (!this) {
throw new TypeError();
}
length = this.length;
if (length === 0 || pivot >= length) {
return -1;
}
if (pivot < 0) {
pivot = length - Math.abs(pivot);
}
for (i = pivot; i < length; i++) {
if (this[i] === searchElement) {
return i;
}
}
return -1;
};
}我需要这个,因为我们仍然需要支持IE8,但在IE8中,indexOf()函数似乎是添加了enumerable的。这意味着,当使用for..in循环遍历数组时,它会出现,如下所示:
var a = [];
a[0]=123;
a[1]=456;
for(var value in a) {
alert(value); // this even alerts "indexOf", if the polyfill above is loaded, and this is a big problem
}有没有可能让polyfill“不可枚举”,这样我就可以在IE8中使用Array.indexOf(),但它不会出现在for..in循环中?
发布于 2014-01-16 23:22:10
一般来说,您可以使用Object.defineProperty将属性添加为不可枚举的属性
Object.defineProperty(Array.prototytpe, 'indexOf', {
enumerable : false,
value : function(){ /* my polyfill code */}
});但是,正如你可能已经猜到的那样,在IE8中没有对它的支持,所以你只能使用@tkone的解决方案,用hasOwnProperty过滤for..in。
另一个伪解决方案是创建一个将数组参数传递给的函数:
function indexOf(array, searchElement, fromIndex) {
if (Array.prototype.indexOf) return array.indexOf(searchElement, fromIndex);
/* my polyfill code with array instead of this*/
}简单地使用它而不是原生indexOf:
[1,2,3].indexOf(2); // change to:
indexOf([1,2,3], 2);您还可以将函数命名为空间,这样当您不再为IE8而烦恼时,请记住将其更改回标准:
IhateIE8.indexOf = ...发布于 2014-01-16 23:18:33
枚举对象的成员时,应使用hasOwnProperty。
var a = [];
a[0] = 123;
a[1] = 456;
for(var value in a){
if(a.hasOwnProperty(value)){
alert(value);
}
}但是为什么不只做一个简单的for循环(或者像forEach这样的多填充操作)呢?
发布于 2014-01-16 23:23:08
是否可以使polyfill“不可枚举”,这样我就可以在IE 8中使用Array.indexOf(),但它不会出现在for..in循环中?
官方的答案是肯定的(参见defineProperty和enumerable),但只针对IE8及更低版本的not really。
我不认为这是一个好主意(见评论)。
https://stackoverflow.com/questions/21165580
复制相似问题