我在约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()
工作?
答案 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)
答案 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中,您仍然需要应用上述技巧将参数转换为实际数组。