这个问题又激起了个人八卦之心!react
在一番寻找以后,找到了彷佛是目前网上仅存的 Brendan Eich 本人探讨 arguments 的资料,是一份录音:https://web.archive.org/web/20110822021124/http://minutewith.s3.amazonaws.com/amwb-20101115.mp3 (来自 aminutewithbrendan.com 这个已经被关闭的网站,彷佛是和当时的赞助事件调查有关因此被关掉了,可是 archive.org 有存档哈哈)web
大体上,BE 本人也认可 arguments 的设计是由于当时只花了十天因此整得太糙了。在正式规范化 JavaScript 的时候,Microsoft 曾经有人提出把 arguments 改为真正的 Array,BE 本人甚至都打算动手改实现了,可是 MS 那边回去商量了下又回来以为多一事不如少一事,不改了。因而这个糟糕的设计就今后成为了规范... 这是 1997 年的初版 ES 规范。数组
除了 arguments.callee 以外,还有一个神奇的 quirk,那就是 arguments 和实际的参数变量之间的迷之绑定。规范里是这么说的:less
In the case when iarg is less than the number of formal parameters for the function object, this property shares its value with the corresponding property of the activation object. This means that changing this property changes the corresponding property of the activation object and vice versa. The value sharing mechanism depends on the implementation.
换言之,假设一个函数的第一个参数是 a,当你修改 a 的值的时候,arguments[0] 也会同步变化:ide
(function (a) { console.log(arguments[0] === a) // -> true console.log(a) // -> 1 // 修改 arguments arguments[0] = 10 console.log(a) // -> 10 // 修改参数变量 a = 20 console.log(arguments[0]) // -> 20 })(1,2)
后面的事情你也知道了,ES 规范是要向后兼容的,并且上面的这个 quirk 使得它在引擎实现中须要不少特殊处理,一旦改动,兼容性影响巨大,因此它永远也改不了了。听说在 ES5 讨论时也有人提出要把 arguments 改为 Array 的 subclass,可是很快就不了了之,只是在 strict mode 下对 arguments.callee 和上面的绑定 quirk 进行了限制。直到 ES6 终于对 arguments 提供了一个替代品 - rest parameters:函数
function foo (...args) { // 这里 args 终因而真正的 Array 了! }