写点什么

ES6 新特性详解 - 解构赋值

作者:yuanyxh
  • 2024-09-14
    中国香港
  • 本文字数:2181 字

    阅读完需:约 7 分钟

ES6 新特性详解 - 解构赋值

内容简述

理解并详细讲述 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 操作,这意味着我们也能对基本数据类型进行结构,但不包括 nullundefined


// 解构字符串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 为产出的值。

参考资料

  • 《JavaScript 高级程序设计》

  • 《你不知道的 JavaScript》

  • MDN#JavaScript


发布于: 刚刚阅读数: 5
用户头像

yuanyxh

关注

站在巨人的肩膀上 2023-08-19 加入

web development

评论

发布
暂无评论
ES6 新特性详解 - 解构赋值_js_yuanyxh_InfoQ写作社区