WEB学习进阶之路 - arguments对象和扩展运算符
【摘要】 arguments对象arguments对象是传递给函数参数的类数组对象先看个例子:function fun(a, b, c){ console.log(arguments)}fun(1, 2, 3)可以看到,arguments像数组一样,有从0开始的索引,也有length属性但是没有数组的join, forEach等方法。 所以才有上面的”类数组对象“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}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)