Array.prototype.slice填充程序,用于旧版Internet Explorer中的非阵列



我有兴趣找到或编写一个伪填充程序,以允许Array.prototype.slice支持非数组(同时在浏览器之间以相同的方式工作)。

我知道有一些接口,比如NamedNodeMap、HTMLCollection等,可以转换,例如,在Firefox中,但在IE<=8.

两个问题:

  1. IE真的不能像一些人所说的那样处理论点对象吗?(我只安装了IE 10,即使在IE5怪癖/IE7模式下也能很好地工作(手工制作的类似数组的对象也很好)。)
  2. 当应用Array.prototype.slice.call()时,我可以使用什么样的鸭子类型来全面支持某些浏览器中支持的所有非数组类型?例如,我可能会将item的类型作为一个函数,并在提供像0这样的样本号时尝试获取一个有效值。Firefox和IE8都接受字符串形式的长度(解析为整数)。只要DOM对象具有length属性,像Firefox这样的浏览器会类似地处理它吗

这是最近提出的一个相关问题,它使这个旧问题被重新发现。

在.slice()的MDN页面上,有一个适用于Array.prototype.slice()的polyfill,它将与所有浏览器一起工作,以复制任何类似数组的对象。由于这个polyfill只适用于旧版本的IE,因此polyfill从对旧版本IE中失败的东西进行特定测试开始(因此它只在需要时安装自己)。

try {
    // Can't be used with DOM elements in IE < 9
    _slice.call(document.documentElement);
} catch (e) {
    // we know we're in IE < 9 here
}

polyfill,然后使用标准测试来查看对象是否是真实的数组:

// test if this is an actual array
if (Object.prototype.toString.call(this) === '[object Array]')

因此,在实际阵列上,使用了常规的内置.slice()。然后,polyfill只需使用.length[index]来读取在任何类似数组的对象上都是安全的内容,就可以实现自己的复制功能,并将复制到新数组中的内容返回。


针对您的具体问题:

IE真的不能像一些人所说的那样处理论点对象吗?(我只安装了IE 10,即使在IE5怪癖/IE7模式下也能很好地工作(手工制作的类似数组的对象也很好)。)

arguments对象是一个类似于本地Javascript数组的对象(不是主机对象,也不是真正的数组),因此复制它没有什么特别的问题。在strict模式下,arguments对象添加了一些新的限制,但仍然可以复制它。复制适用于所有浏览器的arguments对象的常用方法是:

var items = Array.prototype.slice.call(arguments, 0);

必须使用Array.prototype.slice,因为arguments对象本身不是数组,也没有数组方法

当应用array.prototype.stice.call()时,我可以使用什么样的鸭子类型来全面支持某些浏览器中支持的所有非数组类型?例如,我可能会将item的类型作为一个函数,并在提供像0这样的样本号时尝试获取一个有效值。Firefox和IE8都接受字符串形式的长度(解析为整数)。只要DOM对象具有length属性,像Firefox这样的浏览器会类似地处理它吗?

Object.prototype.toString.call(this) === '[object Array]'是测试某个东西是否是实际数组的万无一失的方法。除了测试对象是否具有.length属性以及是否可以使用[index]读取值而不引发异常之外,我不知道有什么鸭子类型的方法可以查看某个对象是否是类似数组的对象。

如果你想在尽可能多的旧浏览器和尽可能多类型的非数组对象上工作,那么我建议你在MDN页面上使用上面链接的polyfill,因为这是它专门设计的。

由于世界(终于)开始超越旧版本的IE,如果您现在只支持IE9及以上版本,那么您可以在所有类似数组的对象上使用Array.prototype.slice.call()方法(任何具有.length属性的对象,该属性对应于可以通过[i]使用整数索引访问的项的数量,并且您甚至不需要polyfill。

最新更新