内容简述
理解并详细讲述 ES6+ 新特性:解构赋值,内容有误欢迎指正。
对象解构赋值
对对象进行解构,提取内部属性,语法如下
const obj = { name: 'yuanyxh', age: 22 };
// 解构const { name } = obj;console.log(name); // yuanyxh
// 类似于const name = obj.name;console.log(name); // yuanyxh
复制代码
上述操作提取了 obj 对象身上的指定属性 name。此外,解构赋值还支持对属性重命名及连续解构。
const obj = { name: 'yuanyxh', age: 22, blog: { addr: 'yuanyxh.com' }};
// 解构并重命名const { name: myName } = obj;console.log(myName); // yuanyxh
// 类似于const myName = obj.name;console.log(myName); // yuanyxh
// --------------------
// 连续解构const { blog: { addr }} = obj;console.log(addr); // yuanyxh.com
// 类似于const addr = obj.blog.addr;console.log(addr); // yuanyxh.com
复制代码
在解构对象上不存在的属性时, JS 引擎并不会报错,而是与变量声明未赋值时一样,变量值为 undefined
const obj = { name: 'yuanyxh', age: 22 };
// 解构const { linkIn } = obj;console.log(linkIn); // undefined
// 类似于const linkIn = obj.linkIn;console.log(linkIn); // undefined
复制代码
在不确定指定属性是否存在目标对象上时,可以给指定属性一个默认值
const obj = { name: 'yuanyxh', age: 22 };
// 解构并赋默认值const { name = '无名氏', linkIn = 'github.com/yuanyxh' } = obj;console.log(name); // yuanyxhconsole.log(linkIn); // github.com/yuanyxh
// 相当于const name = obj.name !== undefined ? obj.name : '无名氏';console.log(name); // yuanyxhconst linkIn = obj.linkIn !== undefined ? obj.linkIn : 'github.com/yuanyxh';console.log(linkIn); // github.com/yuanyxh
复制代码
函数参数同样支持解构操作
function concat({ name, age, linkIn = 'github.com/yuanyxh' }) { return ( 'my name is ' + name + ', ' + 'I am ' + age + ' years old this year, ' + 'you can go to my github homepage to meet me: ' + 'https://' + linkIn );}
const introduce = concat({ name: 'yuanyxh', age: 22 });console.log(introduce); // my name is yuanyxh...
复制代码
解构会对目标数据进行 ToObject 操作,这意味着我们也能对基本数据类型进行结构,但不包括 null 和 undefined
// 解构字符串const { length } = '123456';console.log(length); // 6
// 类似于const length = '123456'.length;console.log(length); // 6
复制代码
我们还可以使用 ES6 新语法 ...target 将剩余属性重新收集为一个新对象或新数组
const obj = { name: 'yuanyxh', age: 22, linkIn: 'github.com/yuanyxh', hobby: '编程,书籍,逆向...'};
// 收集剩余属性const { name, age, ...other } = obj;console.log(other); // { linkIn: 'github.com/yuanyxh', hobby: '编程,书籍,逆向...' }
复制代码
数组解构赋值
数组的解构与对象解构语法类似
const arr = [1, 2, 3, 4, 5];
// 解构const [a, b] = arr;console.log(a, b); // 1 2
// 类似于const iter = arr[Symbol.iterator]();const a = iter.next().value;const b = iter.next().value;console.log(a, b); // 1 2
复制代码
数组解构还支持跳过特定元素获取后面的元素值
const arr = [1, 2, 3, 4, 5];
// 解构const [a, , , b] = arr;console.log(a, b); // 1 4
// 类似于const iter = arr[Symbol.iterator]();const a = iter.next().value;iter.next();iter.next();const b = iter.next().value;console.log(a, b); // 1 4
复制代码
同时,数组解构与对象解构一样支持 默认值、函数参数解构 与 收集剩余数据 操作,不支持 连续解构,以 默认值 举例
const arr = [1, 2, 3, 4, 5];
// 默认值const [a, , , , e, f = 6] = arr;console.log(a, e, f); // 1 5 6
// 相当于const iter = arr[Symbol.iterator]();const a = iter.next().value;iter.next();iter.next();iter.next();const e = iter.next().value;const f = iter.next().value !== undefined ? iter.next().value : 6;console.log(a, e, f); // 1 5 6
复制代码
虽然数组的解构与对象解构语法类似,且 MDN 文档上也称之为解构赋值,但我个人认为两者是不同的,[element] = iterator 解构语法不仅能够解构数组,而且能够解构一切被标识为 iterable 的对象
// 自定义可迭代对象function createIterator() { let i = 0; return { [Symbol.iterator]() { return { next() { return { done: i > 5, value: i++ }; } }; } };}const [a, b, c, d, e, f, g = 6] = createIterator();console.log(a, b, c, d, e, f, g); // 1 2 3 4 5 6
复制代码
关于 iterable 可迭代对象,以后会详解解析,也可自行搜索答案,现在只需要知道可迭代对象必须具有以下几个特点
能够识别自身为 iterator,即具有 Symbol.iterator 方法
Symbol.iterator 必须返回一个对象,且对象拥有 next 方法
next 方法必须返回一个具有 done 属性和 value 属性的对象,done 标识这个迭代器是否被消耗完毕,value 为产出的值。
参考资料
评论