1. 甚么是 arguments
MDN 上说明:
arguments 是两个类字符串第一类。代表者传予两个function的模块条目。他们先用两个范例简单如是说下 JavaScript 中的 arguments 长甚么模样。
继续执行结论是:
貌似,结论是个字符串,但并并非或者说的字符串,因此说 arguments 是两个类字符串的第一类(想如是说或者说字符串与类字符串第一类的差别能始终翻到最终)。
再看一看 arguments 则表示的文本,其则表示了表达式继续执行时传至表达式的大部份模块。在下面的范例中,代表者了传至 `printArgs` 表达式中的五个模块,能依次用 `arguments[0]`、 `arguments
2. arguments 操作方式
2.1 arguments length
arguments 是个类字符串第一类,其包涵两个 `length` 特性,能用 `arguments.length` 来获得传至表达式的模块个数。
继续执行结论如下:
2.2 arguments 转字符串
通常使用下面的方法来将 arguments 转换成字符串:
还有两个更简短的写法:
在这里,只是简单地调用了空字符串的 slice 方法,而没有从 Array 的原型层面调用。
为甚么下面两种方法能转换呢?
首先,slice 方法得到的结论是两个字符串,模块便是 arguments。事实上,满足一定条件的第一类都能被 slice 方法转换成字符串。看个范例:
继续执行结论是:
从下面范例能看出,条件就是: 1) 特性为 0,1,2…;2) 具有 length 特性;
另外,有两个需要注意的地方就是,不能将表达式的 arguments 泄露或者传递出去。甚么意思呢?看下面的几个泄露 arguments 的范例:
下面的做法就直接将表达式的 arguments 第一类泄露出去了,最终的结论就是 V8 引擎将会跳过优化,导致相当大的性能损失。
你能这么做:
那就很好奇了,他们每次使用 arguments 时通常第一步都会将其转换为字符串,同时 arguments 使用不当还容易导致性能损失,那么为甚么不将 arguments 直接设计成字符串第一类呢?
这需要从这门语言的一开始说起。arguments 在语言的早期就引入了,当时的 Array 第一类具有 4 个方法: toString、 join、 reverse 和 sort。arguments 继承于 Object 的很大原因是不需要这五个方法。而现在,Array 添加了很多强大的方法,比如 forEach、map、filter 等等。那为甚么现在不在新的版本里让 arguments 重新继承自 Array呢?其实 ES5 的草案中就包涵这一点,但为了向前兼容,最终还是被委员会否决了。
2.3 修改 arguments 值
在严格模式与非严格模式下,修改表达式模块值表现的结论不一样。看下面的两个范例:
输出:
另两个非严格模式的范例:
输出结论为:
从下面的两个范例中能看出,在严格模式下,表达式中的模块与 arguments 第一类没有联系,修改两个值不会改变另两个值。而在非严格模式下,两个会互相影响。
2.4 将模块从两个表达式传递到另两个表达式
下面是将模块从两个表达式传递到另两个表达式的推荐做法。
2.5 arguments 与重载
很多语言中都有重载,但 JavaScript 中没有。先看个范例:
继续执行结论为:
因此,JavaScript 中,表达式并没有根据模块的不同而产生不同的调用。
是并非 JavaScript 中就没有重载了呢?并并非,他们能利用 arguments 模拟重载。还是下面的范例。
继续执行结论如下:
3. ES6 中的 arguments
3.1 扩展操作方式符
直接上栗子:
继续执行结论是:
简洁地讲,扩展操作方式符能将 arguments 展开成独立的模块。
3.2 Rest 模块
还是上栗子:
继续执行结论是:
从下面的结论能看出,Rest 模块则表示除了明确指定剩下的模块集合,类型是 Array。
3.3 默认模块
栗子:
继续执行结论是:
可见,默认模块对 arguments 没有影响,arguments 还是仅仅则表示调用表达式时所传至的大部份模块。
3.4 arguments 转字符串
`Array.from()` 是个非常推荐的方法,其能将大部份类字符串第一类转换成字符串。
4. 字符串与类字符串第一类
字符串具有两个基本特征:索引。这是一般第一类所没有的。
他们利用 `obj[0]`、`arr[0]` 都能取得自己想要的数据,但取得数据的方式确实不同的。`obj[0]` 是利用第一类的键值对存取数据,而 `arr[0]` 却是利用字符串的索引。事实上,Object 与 Array 的唯一差别就是 Object 的特性是 string,而 Array 的索引是 number。
下面看一看类字符串第一类。
伪字符串的特性就是长得像字符串,包涵一组数据以及拥有两个 length 特性,但是没有任何 Array 的方法。再具体的说,length 特性是个非负整数,上限是 JavaScript 中能精确表达的最大数字;另外,类字符串第一类的 length 值无法自动改变。
如何自己创建两个类字符串第一类?
继续执行结论是:
也就是说 Foo 的实例拥有 Array 的大部份方法,但类型并非 Array。
如果不需要 Array 的大部份方法,只需要部分怎么办呢?
继续执行结论是:
参考:
1. JavaScript中的字符串与伪字符串的差别
3. Avoid modifying or passing `arguments` into other functions
4. Optimization killers · petkaantonov/bluebird Wiki · GitHub
5. Why isnt a functions arguments object an array in Javascript?
7. Advanced Javascript: Objects, Arrays, and Array-Like objects
8. JavaScript 特殊第一类 Array-Like Objects 详解
9. What is a good way create a Javascript array-like object?