这是一个最近提出的相关问题,导致这个较旧的问题被重新发现。
Array.prototype.slice()
在MDN 页面上有一个用于 .slice() 的 polyfill ,它适用于所有浏览器,用于复制任何类似数组的对象。因为只有旧版本的 IE 才需要这个 polyfill,所以 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 确实不能像某些人所说的那样与 arguments 对象一起使用吗?(我只安装了 IE 10,即使在 IE5 quirks/IE7 模式下也能正常工作(对于手工制作的类似数组的对象也很好)。)
arguments 对象是一个原生的 Javascript 类数组对象(不是宿主对象,也不是真正的数组),因此制作它的副本没有特别的怪癖。arguments
模式中的对象添加了一些新限制strict
,但仍然可以复制它。arguments
制作适用于所有浏览器的对象副本的常用方法是:
var items = Array.prototype.slice.call(arguments, 0);
必须使用Array.prototype.slice
,因为 arguments 对象本身不是数组,也没有数组方法。
当与 Array.prototype.slice.call() 一起应用时,我可以使用什么样的鸭子类型来全面支持某些浏览器中支持的所有非数组类型?例如,我可能会将 item 类型作为函数进行回避,并在提供像 0 这样的样本编号时尝试返回有效值。Firefox 和 IE8 都接受长度甚至是字符串(解析为整数)。只要 DOM 对象具有长度属性,像 Firefox 之类的浏览器是否同样可以使用它?
Object.prototype.toString.call(this) === '[object Array]'
是测试某物是否为实际数组的万无一失的方法。.length
除了测试对象是否具有属性以及是否可以[index]
用来读取值而不会导致异常之外,我不知道有任何鸭子类型方法来查看某物是否是类似数组的对象。
如果您想在尽可能多的旧浏览器和尽可能多的非数组对象类型上工作,那么我建议您在 MDN 页面上使用上面链接的 polyfill,因为它是专门设计的。
由于世界(最终)开始超越旧版本的 IE,如果您现在可以只支持 IE9 及更高版本,那么您可以Array.prototype.slice.call()
在所有类似数组的对象上使用该方法(任何具有.length
对应于许多项目可以通过整数索引访问,[i]
您甚至不需要 polyfill。