ES6——对象的解构赋值
程序员文章站
2022-07-02 10:37:34
...
对象的解构赋值,用于从一个现有的对象取值,将其中所有可遍历但尚未赋值的属性,分配到指定的对象上面,所有的键和他们的值都会“浅拷贝”到新对象上面。
//解构赋值
let {x,y,...z} = {x:1,y:2,a:3,b:4,c:{ca : 5}}
//结果如下:
x //1
y //2
z //{a:3,d:4,c:{ca:5}}
在上面的代码中,等号右边的对象的属性x,y,a,b,c都是可遍历的,但是x和y已经被读取,所以z接收的是剩下的几个属性。
需要注意的是,在进行对象的解构赋值时,语法上有如下要求:
1. 要求等号右边必须是对象。如果等号右边不是对象的话,编译器会尝试将等号右边的值转换为对象,如果转换失败的话,会返回运行时错误。根据JavaScript的类型转换知识,我们得出结论:如果在进行对象解构赋值时,等号右边是undefined和null的话,会报错,因为二者不能转换成对象。
// 因为转换对象失败,而报错的解构赋值
let { x, y, ...z } = null; // 运行时错误
let { x, y, ...z } = undefined; // 运行时错误
2. 要求解构赋值必须是最后一个参数,否则报错。
// 因为解构赋值不是最后一个参数而报错
let { ...x, y, z } = obj; // 句法错误
let { x, ...y, ...z } = obj; // 句法错误
再次强调:解构赋值是浅拷贝,如果键值是复合类型(数组、对象、函数),那么解构赋值拷贝的会是引用而不是值的副本。
// 解构赋值浅拷贝示例
let obj = {
a : 1,
b : {
ba : 2
}
}
let {...x} = obj;
obj.a.b.ba = 3;
x.a.b.ba // 3;
在上述代码中,由于是浅拷贝的原因,更改obj对象的属性时,x的属性也同样被更改。再想的深入一些,浅拷贝同样不能拷贝到引用对象的原型链,x同样不会获得obj原型链上的属性。例子如下://解构赋值无法获取原型链上的属性
let obj = {
a : 1,
b : {
ba : 2
}
}
obj2 = {
c : "属性c"
}
obj.prototype = obj2;
let {...x} = obj;
x.c //undefined
对象的解构赋值应用范围很广,适配器模式就是其中一种应用范围。
所谓适配器模式,简言之,就是将一个类(对象)的接口(方法)转换成另外的一个接口,已解决类(对象)之间接口不兼容的问题的一种设计模式。
假设我们现在有一个基础的类baseClass,baseClass有一个对外的接口名为 functionA。
// 基础类baseClass
class baseClass{
//构造器
constructor(){
//基础类的构造器
},
//类的某些属性和方法,再次省略
...
//类的对外接口A
functionA({a,b}){
var {a1,b1} = {a,b};
return a1 + b1;
}
}
这个类baseClass是我们之前工程的代码,接口 functionA 一直都很好用,但是某一天,我们的需求变了,需要我们为functionA 接口多传入两个新参数,进行更加复杂的运算。如果我们可以修改baseClass类的结构的话,我们可以添加一个新的接口。
// 基础类baseClass
class baseClass{
//构造器
constructor(){
//基础类的构造器
},
//类的某些属性和方法,再次省略
...
//类的对外接口A
functionA({a,b}){
var {a1,b1} = {a,b};
return a1 + b1;
}
functionB({a,b,c,d}){
var {a1,b1,c1,d1} = {a,b,c,d};
var tmp = c1 * d1;
var tmp2 = this.functionA(a1,b1);
return tmp1 + tmp2;
}
}
下一篇: 家庭妇女菜篮子的养生术