WEB学习进阶之路 - arguments对象和扩展运算符
arguments对象
arguments对象是传递给函数参数的类数组对象
先看个例子:
function fun(a, b, c){ console.log(arguments) } fun(1, 2, 3)
可以看到,arguments像数组一样,有从0开始的索引,也有length属性
但是没有数组的join, forEach等方法。 所以才有上面的”类数组对象“
arguments有两个特殊的属性
arguments.callee
arguments.Symbol.iterator
这两个具体是干嘛的呢?
callee
可以看上面那个截图,是不是是一个函数,并且有三个参数a,b,c。咱们打印看下
发现了什么,返回的是函数本身,对了,这个callee属性就是函数对象本身。
优势1:代替不具备具名函数表达式
这个callee的被发明出来是因为早期的js函数不具备具名函数表达式(named function expression),所以早期函数表达式无法实现递归
例如: ['a' ,'b', 'c'].map(function(n) {
//这里无法实现递归,所以就发明了callee来代替函数本身
})
优势2:解函数名称的耦合
比如
function a() { a()};
如果要改名函数名为b,那么内部的调用也需要修改,而直接使用arguments.callee()就不会有问题。
当然有好处也有不少坏处,而且在严格模式'use strict'下,callee是被禁用的,调用会报错。
缺陷1:改版函数内部的this指向
因为第二次以后是使用arguments调用的,所以this就变了。
缺陷2:对于函数的尾递归优化和引用优化产生性能影响(具体是什么影响,这里就不展开讲了,后续有空在说说这个)。
Symbol.iterator
主要是用于迭代for ... of和展开(...)运算符
var arr = [1,2,3]; for (let i of arr) { console.log(i) }
for of可用于Array,TypeArray, Map, Set, String这五种对象的迭代
for in主要用于Object的迭代
这里有个 迭代 和 协程 的概念,后续补充。
扩展运算符(...)
实参中的扩展运算符
function fun(...args) { console.log(args) } fun(1,2,3) //[1,2,3] fun(1) // [1]
可以看出实参中的...运算符是可变参数的意思。
其余地方的扩展运算符
1. 用于拷贝参数的值到当前对象中,对于相同的键值会被当前对象覆盖
const obj1 = {a:1, b:2}; const obj2 = {...obj1, c: 3, b: 4}; console.log(obj2); //{a: 1, b: 4, c: 3}
2. 参数拷贝,对于基础数据是复制,对于对象是其引用,如下:
const obj1 = {a:1, b:2, c:{age: 3}}; const obj2 = {...obj1}; obj2.a = 2; obj2.c.age = 100; console.log(obj1); //{a: 1, b: 2, c: {age: 100}} console.log(obj2); //{a: 2, b: 2, c: {age: 100}}
3. 拆分字符串
console.log([...'xyg']) //["x", "y", "g"]
4. 剩余运算
const arr1 = {a:1,b:2,c:3}; const {a, ...b} = arr1; console.log(a); // 1 console.log(b); // {b: 2, c: 3}
- 点赞
- 收藏
- 关注作者
评论(0)