哈喽,大家好,今天是2月的最后一天,9102年已经过去了六分之一,?想想有点害怕啊!害怕是解决不了任何问题滴!珍惜眼前吧,各位宝宝们!
speak is cheap!
扩展运算符(...)与对象一起能做什么?
大致可以分三种:对象的解构赋值、对象的拷贝、对象的合并;
1.对象的解构赋值
对象的解构赋值是把原对象里面的值浅拷贝到新的对象之中。例如:
let {a,b,...z} = {a:1,b:2,c:3,d:4};
console.log("a",a,"b",b,"z",z); //a 1 b 2 z {c: 3, d: 4}
注意:
(1)对象的解构赋值的拷贝其实是浅拷贝
let {a,b,...z}={a:1,b:2,n:{c:3,d:4}};
console.log("a",a,"b",b,"z",z); //a 1 b 2 z {n:{c:1,d:7}};
z.n = {c:1,d:7};
console.log("z",z);//{n:{c:1,d:7}}
(2)对象解构赋值的右边必须是对象,否则会报错;
let {a,b,...z}=undefined; //运行时报错
let {a,b,...z}=null; //运行时报错
(3)解构赋值必须是最后一个参数,否则会报语法错误
let {a,...z,b}={a:1,b:2,n:{c:3,d:4}}; //SyntaxError
(4) 带...的解构赋值不会拷贝继承自原型对象的属性
let o1 = {
a:1
};
let o2 = {
b:2
};
o2.__proto__ = o1;
let {...o3 } = o2;
o3//{b:2}
o3.a //undefined
ps:
const o = Object.create({x:1,y:2});
o.z = 3;
let {x,...{y,z}} = o;
x//1
y//undefined
z//3
Object.creat(p1,p2)可以传两个参数,第一个对象是必须的,表示所创建对象的prototype;第二个对象是可选的,用于定义所创建对象的各个属性(比如,writable、enumerable)。
上面的例子中,x和y都是o的原型上的属性,x的解构赋值是简单的解构赋值,但是{y,z}的解构赋值是复合的解构赋值,y是o的原型上的属性,所以不能进行解构赋值,z是对象上的属性,可以解构赋值。
2.拷贝。扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象中。
let o={a:1,b:2}
let o2 = {...o}
o2 //{a:1,b:2}
这等同于使用Object.assign方法
let b = {...a};
//等同于
let b = Object.assign({},a);
以上的方法之拷贝对象实例的属性,如果想拷贝对象原型的属性,可采用如下方法。
//写法一
const cloneObj1 = {
__proto__:Object.getPrototypeOf(obj),
...obj
};
//写法二
const cloneObj2 = {
object.create(Object.getPrototypeOf(obj)),
...obj
};
方法一的proto属性在非浏览器环境不一定部署,所以方法二更好一些。
3.合并对象
let xy = {...x,...y};
//等同于
let xy = Object.assign({},x,y);
(1)后面的强度比前面的强度强,所以如果有相同属性,在合并后的对象中,后面的会覆盖前面的;
let a={x:2,y:3,z:6}
let b={x:1,y:2,q:1}
let aWithDefaults = {...b,...a};
//等同于
let aWithDefaults = Object.assign({},b,a);
//a {x: 2, y: 3, z: 6}
// b {x: 1, y: 2, q: 1}
// aWithDefaults {x: 2, y: 3, q: 1, z: 6}
(2)扩展运算符后边可以跟表达式
const x=2;
const obj = {
...(x > 1 ? {a: 1} : {}),
b: 2,
};
console.log("obj",obj); //{a:1,b:2}
所有,我说清楚了吗?如有疑问或建议,就给我留言吧,等你……
愿我们有能力不向生活缴械投降---Lin