ES6学习笔记(二):认识解构赋值

一、什么是解构赋值

在ES6及以后版本的JavaScript中,允许按照一定的模式从数组和对象中提取值,然后再对变量进行赋值,这种操作就被称为解构赋值,解构赋值相当于两个步骤,先是解构分解数据结构,然后再为变量赋值。

1.数组的解构赋值

一个小栗子

{
	let a = 1;
	let b = 2;
	let c = 3;

	// 上面的代码等同于下面
	let [a,b,c] = [1,2,3];
	console.log(a,b,c); // 输出1 2 3
}

可以看出有了解构赋值的新特性后,对变量的赋值就更加方便了。本质上,解构赋值的语法属于模式匹配,只要等号两边的匹配模式相同(如数组与数组,对象与对象),那么左边的变量就会被赋予相对应的值,顺序是从左往右的。

如果没有匹配成功

{
	let [x,y,z,a] = [1,2,3];
	console.log(x,y,z,a); // x,y,z会输出1 2 3,而a会输出undefined
	let [arr] = 1;
	console.log(arr); // 如果赋值不是数组,模式不同的话就会报错
}

如果解构不成功的话,那么变量的值就会等于undefined,没有定义,没有默认值。

2.数组解构的默认值

ES6内部使用严格相等运算符(===)来判断一个位置是否有值,如果一个数组的成员不严格等于undefined,那么默认值就不会生效,优先使用右边的值。

解构赋值允许指定相应的默认值。

{
	let [foo = true] = [];
	let [x,y = 'web'] = ['a'];
	let [m,n = 'web'] = ['a',undefined];
	console.log(foo); // 输出true
	console.log(x,y); // 输出a web 
	console.log(m,n); // 输出a web
}

可以看到如果有默认值的话那么在匹配不成功时就会使用默认值。

默认值可以引用解构赋值的其他变量,但该变量必须已经声明,否则就会报错。

{
	let [x = 1,y = x] = []; // x为1,y也为1
	let [x = 1,y = x] = [2]; // x为2,y为2
	let [x = 1,y = x] = [2,3]; // x为2,y为3
	let [x = y, y = 1] = [] // 报错
}

数组的解构赋值当中,优先匹配等号右边的值,所以第二个和第三个的结果是那样的,但如果默认值当中的变量没有在声明后使用的话就会报错,如第四个例子y就在声明前使用了,因此就会报一个未在初始化之后使用的错误。

3.对象的解构赋值

对象的解构赋值与数组的方式不同,数组的元素是按次序排列的,有相应的索引,变量的取值是由它所在的位置决定的。而对象的属性是没有次序的,因此变量必须与属性同名才能取到正确的值。

对象解构允许我们使用变量的名字匹配对象的属性,匹配成功将对象属性的值赋值给变量。

{
	// 在ES5当中获取属性中的值得方法
	let person = {name : '张三' , age : 20 , sex : '男'};
	person.name;
	person.age;
	person.sex;
	// 在ES6及以后版本中的方法
	let {name,age,sex} = {name : '张三' , age : 20 , sex : '男'};
	console.log(name,age,sex); // 输出张三,20,男

	// 上面的方法相当于下面这样的简写
	let {name:name,age:age,sex:age} = {name : '张三' , age : 20 , sex : '男'};
}

左边结构里的第一个name就是匹配右边的name属性,而第二个name才是变量的名字,将匹配到的name属性的值赋值给左边的name变量。这就是对象解构赋值的机制:先找到同名的属性,然后再赋值给对于的变量,真正被赋值的是后面的变量。

对象结构赋值也可以用于嵌套结构的对象。

{
    let obj = {};
    let arr = [];
    // 匹配左右两边属性名为foo的值,把123赋给了左边foo里的obj.prop属性,bar则是赋值给了arr数组的第0个元素。
    ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
    console.log(obj); // 输出{prop:123}
    console.log(arr); // 输出[true]
}

这里加了括号是为了把这行代码当成表达式运行,否则就会报错。

对象解构赋值的默认值

对象的解构赋值也可以指定默认值,并且默认值生效的条件时对象的属性严格等于undefined(===undefined)。

{
	let { x = 3 } = {}; // x为3
    let { x, y = 5 } = { x: 1 }; // x为1,y为5
    let { x: y = 5 } = {}; // 报错,x还没有定义
	// 如果解构失败,变量的值就为undefined
	let {foo} = { bar : 'a'} // foo为undefined
}

4.字符串的解构赋值

字符串的解构赋值,是将字符串看作一个类似于数组的对象。

{
	let [a,b,c,d] = 'hello'; 
	console.log(a,b,c,d); // 输出 h e l l
}

这样赋值就相当于是数组的索引方式,从左往右匹配

每个类似数组的对象都有一个length属性,因此还可以对length属性解构。

{
	let [length : len] = 'hello';
	console.log(len); // 输出5
}

相当于是对字符串的length属性设置了一个变量,这个变量就等于右边字符串的长度。

5.函数参数的解构赋值

函数调用时,会将实参传递给形参,这个过程其实也就是将实参赋值给形参。因此,函数的参数也可以使用结构赋值。
其规则与数组、对象的解构赋值是一样的,关键是参数用的是哪种解构赋值的方式。

一个小例子:

{
	function a({name,age}){
		console.log(name,age);
	}
	a({name : '小张',age : 20}); // 输出小张,20

	function add({ x, y = 10 }) {
        return x + y;
    }
    let r = add({ x: 20 });
    console.log(r);  // 输出 30
}

二、解构赋值的用途

1.交换变量的值

在ES6以前,没有结构赋值新特性时交换变量是这样的。

	var a = 1
    var temp;
    var b = 2;
    temp = a;
    a = b;
    b = temp;

	// 有了解构赋值后
	let x = 1, y = 3;
    [x, y] = [y, x];

可以看出,用了解构赋值的特性后,在变量交换值上就简单了许多,易读性也很高,很方便。

2.从函数中返回多个值

解构赋值还可以用在函数的返回值当中,可以返回多个值,用数组或者对象的方法。

{
    function func() {
        return [1, 2, 3];
    }
    let [a, b, c] = func();
    console.log(a,b,c); // 输出 1,2,3
    function func2() {
        return {
            foo: 1,
            bar: 2
        };
    }
    let { foo, bar } = func2();
    console.log(foo,bar); // 输出 1,2   
}

3.提取JSON数据

这个算是用处比较广泛的,JSON格式的数据我们会经常用到,因此这个时候用解构赋值的方法去获取JSON数据也是非常方便的。

{
    let json = '{"id" : 42,"state" : "OK","d" : [233,666]}';
    let data = JSON.parse(json); // 把字符串转为JSON格式的数据
    let { id, state, d : num} = data;
    console.log(id, state, num); // 输出 42,"OK",[233,666]
}

总结

可以看到在ES6当中获取属性值得方法比ES5及以前要简单了许多,无论是数组还是对象,都比以前更具有可读性,并且可以应用在许多场合,因此可以多多使用解构赋值这个新特性来实现各种获取值或者赋值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值