摘要:前言前言该篇笔记是第二篇变量的解构赋值。这一章原文链接变量的解构赋值解构赋值解构赋值允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。对象的解构赋值是根据对象值进行匹配。
该篇笔记是第二篇 变量的解构赋值。
这一章原文链接: 变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
解构赋值是对赋值运算符的扩展。
这是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
为变量赋值。
let sample1 = 1;let sample2 = 2;let sample3 = 3;
上面代码使用ES6的数组解构赋值可以写成下面这样。从数组中提取值,按照对应位置,对变量赋值。
let [sample1, sample2, sample3] = [1, 2, 3]; console.log(sample1, sample2, sample3); // 1, 2, 3
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
上面代码在声明变量同时进行了赋值,ES6也可以先声明变量再进行解构赋值,
let sample1, sample2, sample3; // 先申明[sample1, sample2, sample3] = [1, 2, 3];console.log(sample1, sample2, sample3); // 1, 2, 3
有几种情况
注意:
Iterator
接口的数据结构。undefined
。// 解构成功let [sample1, [sample2, sample3]] = [1, [2, 3]]; console.log(sample1, sample2, sample3); // 1, 2, 3// 解构不成功,变量的值就等于undefined。let [sample] = []; // sample 的值为 undefined let [sample1, sample2] = [1]; // sample2 的值为 undefined // 如果等号右边不是数组,也就是不可遍历结构,将会报错let [sample] = 1; // 直接报错,因为等号右边的值是个字面量不可遍历
let sample1, sample2, sample3, sampleN; // 先声明变量再进行解构赋值[[sample1, sample2], sample3, ...sampleN] = [[1, 2], 3, 4, 5]; // 嵌套数组console.log(sample1, sample2, sample3, sampleN); // 1 2 3 [4, 5]let [sample11, sample12] = [1, 2, 3]; // 变量声明并赋值解构let [sample21, ,sample23] = [1, 2, 3];console.log(sample11, sample12); // 不完全解构 1 2console.log(sample21, sample23); // 不完全解构 1 3
当你不想从数组中解构出的值为undefined
,解构赋值允许指定默认值。
注意:
undefined
,默认值才会生效。// 当 值 不存在时,默认值生效let [sample1 = 10, sample2 = 11] = [2];console.log(sample1, sample2); // 2 11 // 当 值 === undefined 时,默认值才会生效let [sample10 = 10, sample11 = 11, sample13 = 12] = [undefined, "", null];console.log(sample10, sample11, sample13); // 10, , null, let [sample21 = 1, sample22 = sample21] = [];console.log(sample21, sample22);let sample30 = 31;let [sample31 = sample30, sample32 = 3] = [];console.log(sample31, sample32);
数组的解构赋值与对象的解构赋值有很大区别
注意:
undefined
。表达式等号左右两边,都要有互相匹配的属性值,才能将右边匹配成功key
的value
值赋值给左边相对应key
的value
,左边的value
值作为变量。
let { sample: sample, sample1: sample2 } = { sample: 10, sample1: 11 }console.log(sample); // 10console.log(sample1) // 报错 sample1 is not definedconsole.log(sample2) // 11
ES6 对对象进行了扩展,对象里的属性与value值可以简写(以后会提到,目前只要知道可以这样用),
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
当属性名与值或方法名相同时,可以简写为一个。
const { log: log } = console; // 可以解构现有对象log(hello); // hello// 上面代码可以简写为下面const { log } = console;log(hello) // hello
在嵌套的对象中使用解构赋值。
// 多重嵌套,还可以嵌套数组let obj = { sample: [ Hello, { sample1: World } ]};let { sample: [sample, { sample1 }] } = obj; console.log(sample,sample1); // Hello World// 或者像这样?给数组或对象添加新内容let obj = {};let arr = [];({ sample: obj.a, sample1: arr[0] } = { sample: 123, sample1: true });console.log(obj); // {a: 123}console.log(arr); // [true]
和数组解构赋值默认值类似,对象的默认值
注意:
undefined
,默认值才会生效。// 当 对象的属性值 不存在时,默认值生效let {sample1 = 10, sample2 = 11} = {sample1:2};console.log(sample1, sample2); // 2, 11 //当 对象的属性值 === undefined 时,默认值才会生效let { sample10 = 10, sample11 = 11, sample12 = 12 } = { sample10: "", sample11: undefined, sample12: null };console.log(sample10, sample11, sample12); // 11, , null// 默认值为变量let {sample21 = 1, sample22 = sample21} = {};console.log(sample21, sample22); // 1, 1let sample30 = 31;let {sample31 = sample30, sample32 = 3} = {};console.log(sample31, sample32); // 31, 3
// 1. 语法错误let sample;{sample:sample} = {sample: 1}; // 直接报错/* 因为 JavaScript 引擎会将{sample}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。*/// 2. 虽然无意义但是合法({} = [true, false]);({} = abc);({} = []);// 3. 数组使用对象的解构赋值,let { 0: sample0, 1: sample1 } = [1, 2];console.log(sample0, sample1); // 1, 2
字符串也可以解构赋值。
当字符串进行解构赋值的时候,字符串被转换成了一个类数组。
类数组也有length
属性,所以还可以通过这个方式获取字符串的长度
let { length } = sample;console.log(length); // 6
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
由于**undefined**
和**null**
无法转为对象,所以对它们进行解构赋值,都会报错。
// 数值与布尔值 进行解构赋值let { toLocaleString: sampleNum } = 111;console.log(sampleNum === Number.prototype.toLocaleString);let { toString: sampleBol } = true;console.log(sampleBol === Boolean.prototype.toString);// undefined 和 null 进行解构赋值let { prop: x } = undefined; // 直接报错 TypeErrorlet { prop: y } = null; // 直接报错 TypeError
函数参数进行解构赋值,函数参数需要为可解构赋值的解构。
// 参数为数组时,参数在传入函数的时候,数组参数就被解构成变量 sample1 和 sample2 。function addNumberArr([sample1, sample2]) { return sample1 + sample2;}console.log(addNumberArr([4, 4])); // 8// 参数为对象时,函数通过对这个参数进行解构 得到变量 sample1 和 sample2 的值。function addNumberObj({ sample1, sample2 }) { return sample1 + sample2;}console.log(addNumberObj({ sample1: 10, sample2: 20 })); // 30
函数参数的解构也可以使用默认值。
// 函数通过对这个参数进行解构,得到变量sample1和sample2的值。// 如果解构失败,sample1和sample2等于默认值。function sample({ sample1 = 0, sample2 = 0 } = {}) { console.log([sample1, sample2]) return [sample1, sample2];}sample({ sample1: 1, sample2: 2 }); // [1, 2]sample({ sample1: 1 }); // [1, 0]sample({}); // [0, 0]sample(); // [0, 0]
什么是圆括号问题呢?
原来在编译器中,无法在解析到等号之前识别一个式子为表达式还是解构赋值等号左边部分,也就是模式匹配中左边的
key
(属性)值。那么如果识别到了圆括号后,编译器该按照什么方式去处理圆括号呢?
ES6 规定,只要有可能导致解构的歧义,就不得使用圆括号。
阮一峰老师建议只要有可能,就不要在模式中放置圆括号。
注意:以下三种情况不能使用圆括号
上面三种情况使用圆括号直接报错。
// 1. 变量声明语句let [(sample)] =[1]; // 直接报错let { sample: ({ sample1: sample1 }) } = { sample: { sample1: 2 } }; // 直接报错// 2. 函数参数也属于变量声明,因此不能带有圆括号。function sampleFn([(sample)]) { return sample; } // 直接报错// 3. 赋值语句的模式({ sample2: sample21 }) = { sample2: 42 }; // 直接报错[({ sample3: sample31 }), { sample4: sample41 }] = [{}, {}];
只有一种情况可以使用圆括号
不能有声明语句,赋值语句的非模式(属性名)部分,可以使用圆括号。
({ sample: (sample) } = {}); // 正确console.log(sample); // undefined
解构赋值主要还是用在对象和数组上,
不用临时变量,怎么交换两个变量的值?可以使用解构赋值简单实现。
// 数组的解构赋值let sample1 = 2;let sample2 = 4;[sample1, sample2] = [sample2, sample1];console.log(sample1, sample2); // 4 , 2
// 解构函数返回的对象function sample() { return [1, 2, 3];}let [sample1, sample2, sample3] = sample();console.log(sample1, sample2, sample3); // 1, 2, 3// 解构函数返回的对象function sample() { return { sample11: 1, sample12: 2, sample13: 3, };}let {sample11, sample12, sample13} = sample();console.log(sample11, sample12, sample13); // 1, 2, 3
可以使用解构赋值一次性提取多个数据
let sampleJson = { id: 11, status: false, data: [{ name: name1 }, { name: name2 }]}let { id, status, data } = sampleJson;console.log(id, status, data);// 11, false, [{ name: name1 }, { name: name2 }]
const { SourceMapConsumer, SourceNode } = require("source-map"); // 示例代码
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/124822.html
摘要:前言该篇笔记是第二篇变量的解构赋值。这一章原文链接变量的解构赋值解构赋值允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。对象的解构赋值是根据对象值进行匹配。 前言该篇笔记是第二篇 变量的解构赋值。 这一章原文链接: 变量的解构赋值解构赋值ES6 允许按照一定模式,从数组和对象中提取值,对...
摘要:另外对于已经声明的变量进行解构赋值时,要非常小心。因此在行首加,将其强制转化为表达式执行。由于和无法转为对象,所以对它们进行解构赋值,都会报错。 let和const let和const是es6新增的两个变量声明关键字,与var的不同点在于: (1)let和const都是块级作用域,在{}内有效,这点在for循环中非常有用,只在循环体内有效。var为函数作用域。 (2)使用let和con...
阅读 716·2023-04-25 19:43
阅读 3912·2021-11-30 14:52
阅读 3788·2021-11-30 14:52
阅读 3856·2021-11-29 11:00
阅读 3786·2021-11-29 11:00
阅读 3872·2021-11-29 11:00
阅读 3560·2021-11-29 11:00
阅读 6111·2021-11-29 11:00