arguments.slice()应该在ES5中工作吗?

时间:2015-06-27 01:51:49

标签: javascript function ecmascript-5 ecmascript-3

我在约41分26秒时看Crockford on Javascript - Act III: Function the Ultimate。他屏幕上的代码使用arguments.slice()causes an error对我来说。

function curry(func){
    var args = arguments.slice(1);
    ...
}

他这样解释:

  

我首先会得到一个参数数组,除了第一个参数,因为   第一个是功能,我不需要那个功能。在这种情况下   我假设我在ES5上,所以我没有做坏事   Array.prototype.apply()技巧。

问题是运行arguments.slice()会导致此错误:

Uncaught TypeError: arguments.slice is not a function

我在现有浏览器上测试肯定有ES5!我可以让代码工作的唯一方法是使用一些"糟糕的"技巧,(他称之为),例如Array.prototype.slice.apply(arguments, [1])[].slice.call(arguments, 1);

他错了吗?他的幻灯片中有拼写错误吗?为什么我的ES5浏览器不能arguments.slice()工作?

3 个答案:

答案 0 :(得分:3)

Quoting TC39成员Allen Wirfs-Brock:

  

直到ECMAScript 5的开发很晚,参数对象才会继承所有的Array.prototype方法。但是"最终草案" TC39于2009年9月批准的ES5没有此功能。

实际上是计划使用Array原型继承参数对象,但是在实践中它broke the web。因此,它在官方发布之前已从最终修订版中删除。

如今,ECMAScript 2015(a.k.a. ES6)标准化,最好的方法是使用rest parameters

function curry(func, ...args) {
  // ...
}

这相当于ES5:

function curry(func) {
  var args = [].slice.call(arguments, 1);
  // ...
}

此功能在Firefox和Edge中已经原生可用,如果您使用Babel等JavaScript编译器,则可在任何地方使用。

答案 1 :(得分:0)

由于arguments类似于数组,您可以使用:

function fn() {
  const args = Array.from(arguments)
}

(如果您有PolyfillBabel

答案 2 :(得分:-2)

arguments对象不是数组。它类似于Array(类似于Array),但除了length之外没有任何Array属性。

您必须先使用所述技巧将其转换为数组。

var slice = Array.prototype.slice;
function curry(func){
    var args = slice.call(arguments, 1); // converts into array
}

参数将继承数组中的所有原型方法,但在最终草案中,此功能已被删除。

https://mail.mozilla.org/pipermail/es5-discuss/2009-August/003112.html

  

我实现逻辑以使Arguments对象继承自Array   在上个星期五的WebKit中,它很快就出现了严重的问题   与Prototype.js不兼容   ...   这打破了至少一些Apple网站和Nasa.gov -   ...   由于这些站点破损,引起了主要的兼容性问题   在一个相当重要的图书馆里,尝试改造是不可行的   像对行为一样的数组。

所以最后,他们不是强迫每个人都改变他们的代码以避免破坏网页,而是恢复了这一变化。因此,即使在ES5中,您仍然需要应用上述技巧将参数转换为实际数组。