为什么arguments是类数组对象
为什么JavaScript里函数的arguments只是array-like object?
JavaScript的函数里面的arguments对象有 .lengh 属性和可以通过 [] 访问,但是确实从Object.prototype继承的。很多时候都会用 Array.prototype.slice.call(arguments) 或者 Array.from(arguments) 转成数组。直接设计成数组不是更好吗?
这个问题又激起了我的八卦之心!
在一番寻找之后,找到了似乎是目前网上仅存的 Brendan Eich 本人探讨 arguments 的资料,是一份录音:https://web.archive.org/web/20110822021124/http://minutewith.s3.amazonaws.com/amwb-20101115.mp3 (来自 aminutewithbrendan.com 这个已经被关闭的网站,似乎是和当时的赞助事件调查有关所以被关掉了,但是 archive.org 有存档哈哈)
大致上,BE 本人也承认 arguments 的设计是因为当时只花了十天所以整得太糙了。在正式规范化 JavaScript 的时候,Microsoft 曾经有人提出把 arguments 改成真正的 Array,BE 本人甚至都打算动手改实现了,但是 MS 那边回去商量了下又回来觉得多一事不如少一事,不改了。于是这个糟糕的设计就从此成为了规范... 这是 1997 年的第一版 ES 规范。
除了 arguments.callee 之外,还有一个神奇的 quirk,那就是 arguments 和实际的参数变量之间的迷之绑定。规范里是这么说的:
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] 也会同步变化:
(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 了!
}
BE 本人并没有提到为什么一开始会把 arguments 设计成对象,因此我们也只能做猜测。但一个合理的推测是,ES1 里面的 Array.prototype 其实很弱,只有四个方法:toString, join, reverse 和 sort - 连 push, pop, shift, unshift, splice 都没有!而 forEach, filter, map, reduce 这些有用的方法更是 ES5 才添加进来的。所以当时 arguments 就算真的继承自 Array 貌似也没什么大用,所以就这样被放过了... 当然,这只是我们的猜测,估计 BE 自己今天也说不清自己当时为什么这么干的了吧。
为什么arguments是类数组对象的更多相关文章
- 类数组对象 实参对象arguments
先看实参对象arguments 之前对argument有点印象,知道它不是真正的数组,但也可以arguments[0]和arguments.length.今天详细的记录一下. js的默认行为:省略的实 ...
- (三十六)类数组对象arguments
类数组对象:arguments 在函数调用时,我们总能见到arguments这个对象,它具体是用来干什么的呢?感觉逼格非常高呢 函数在使用时,我们总会位函数传入各种参数,arguments会将参数储存 ...
- 类数组对象:arguments
在js中调用一个函数的时候,我们经常会给这个函数传递一些参数,js把传入到这个函数的全部参数存储在一个叫做arguments的东西里面,那它到底是什么呢? 一.描述 arguments 是一个对应于传 ...
- 类数组对象arguments 和 数组对象
arguments并不是一个真正的数组,而是一个“类似数组(array-like)”的对象: 就像下面的这段输出,就是典型的类数组对象: {0:12, 1:23} 一.类数组 VS 数组 相同点: 都 ...
- 浅谈js的类数组对象arguments
类数组对象:arguments总所周知,js是一门相当灵活的语言.当我们在js中在调用一个函数的时候,我们经常会给这个函数传递一些参数,js把传入到这个函数的全部参数存储在一个叫做arguments的 ...
- 类数组对象与arguments
类数组对象 所谓的类数组对象: 拥有一个 length 属性和若干索引属性的对象 举个例子: var array = ['name', 'age', 'sex']; var arrayLike = { ...
- 类数组对象与 arguments
类数组对象:拥有一个 length 属性和若干索引属性的对象 var array = ['name', 'age', 'sex']; var arrayLike = { 0: 'name', 1: ' ...
- 简述JavaScript对象、数组对象与类数组对象
问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...
- [Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法
前面有几条都讲过关于Array.prototype的标准方法.这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array. arguments对象 在22条中提到的函数argument ...
随机推荐
- SpringMVC实现JSON与前台交互
这几天忙着做学校的项目,感觉好久没有更新博客了,来整理一下. 由于要实现的功能是表单联动,只能自己去写ajax来实现提交给后台接口了,好久没有写前端,好多东西都忘记了,只能可怜巴巴的用原生的js去实现 ...
- 后台返回json可能会出现的异常解析:java.lang.IllegalStateException: WRITER
在使用filter做权限管理限制访问时,经常是在数据可以正确返回时,在后台日志中却有这个异常抛出,这个现象让人不禁想去一探究竟. 我要做的是在一个filter中拦截所有的请求,并且根据拿到的请求中的参 ...
- Java 常量池存放的是什么
public class Test{ Integer i1 = 127 ; // 常量池本来就有,直接饮用常量池. String s1 = new String("aaaa"); ...
- linhaifeng
http://www.cnblogs.com/linhaifeng/p/7278389.html http://blog.51cto.com/egon09
- 7.python常用模块
1.time 常用表示时间方式: 时间戳,格式化的时间字符串,元组(struct_time) UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时 ...
- iOS 判断数组array中是否包含元素a,取出a在array中的下标+数组方法详解
目前找到来4个解决办法,第三个尤为简单方便 NSArray * arr = @["]; //是否包含 "]) { NSInteger index = [arr indexOfObj ...
- iOS学习之Socket使用简明教程- AsyncSocket
转载自:http://my.oschina.net/joanfen/blog/287238 如果需要在项目中像QQ微信一样做到即时通讯,必须使用socket通讯,本人也是刚学习,分享一下,有什么不对的 ...
- [array] leetcode - 42. Trapping Rain Water - Hard
leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...
- 用keras作CNN卷积网络书本分类(书本、非书本)
本文介绍如何使用keras作图片分类(2分类与多分类,其实就一个参数的区别...呵呵) 先来看看解决的问题:从一堆图片中分出是不是书本,也就是最终给图片标签上:“书本“.“非书本”,简单吧. 先来看看 ...
- 点击button1弹出form2,并在form2中点击button2来调用form1的方法
链接地址:http://www.sufeinet.com/thread-1273-1-1.html 1. private void button1_Click(object sender, ...