别裁伪体亲风雅,转益多师是汝师。这篇文章主要讲述ES6学习 第二章 变量的解构赋值相关的知识,希望能为你提供帮助。
前言该篇笔记是第二篇 变量的解构赋值。
这一章原文链接: 变量的解构赋值
解构赋值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 2
console.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);
对象的解构赋值 对象解构数组的解构赋值与对象的解构赋值有很大区别
注意:
- 对象的解构赋值不再和顺序有关,是与变量名有关,变量必须与属性同名,才能取到正确的值。
- 对象的解构赋值是根据对象key值进行匹配。
- 如果解构不成功,那么值为
undefined
。 - 和数组解构赋值一样,可以对嵌套结构的对象进行解构赋值。
key
的value
值赋值给左边相对应key
的value
,左边的value
值作为变量。let { sample: sample, sample1: sample2 } = { sample: 10, sample1: 11 }
console.log(sample);
// 10
console.log(sample1) // 报错 sample1 is not defined
console.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;
// 直接报错 TypeError
let { 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]
圆括号问题什么是圆括号问题呢?
【ES6学习 第二章 变量的解构赋值】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
- 提取JSON数据
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");
// 示例代码
推荐阅读
- Jenkins安装部署
- #yyds干货盘点#Java ASM系列((094)查找相关的指令)
- openstack的扩展#私藏项目实操分享#
- 千呼万唤,web人脸识别登录完整版来了,这样式我爱了
- 掌握Java的内存模型,你就是解决并发问题最靓的仔
- 在WordPress主题中禁用页脚会停止粘性导航
- 在WordPress Customizer上禁用WordPress自定义CSS seciton
- 禁用全页滚动,低于指定的分辨率
- WordPress中每个活动菜单项的颜色不同