Object.assign
Object.assign: 将所有可枚举属性的值从一个或多个对象复制到目标对象,并返回目标对象
Object.assign可以实现对象的合并。它的语法是这样的:Object.assign(target, ...sources) Object.assign
会将source里面的可枚举属性复制到target
。如果和target的已有属性重名,则会覆盖。同时后续的source会覆盖前面的source的同名属性。
Object.assign是浅复制 —>简单来说:如果只是一层数组或是对象,其元素只是简单类型的元素,那么属于深拷贝(就是一层拷贝,暂时就理解为深拷贝吧!!!!)
实际原理:复杂数据类型名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值,
简单数据类型一经声明键值都存储在栈内存中 所以只一级值做简单数据类型 是深拷贝 如果二级包含引用数据类型就是浅拷贝
展开运算符
let new_obj = { ...obj }; 和Object.assign是同理 二级也是浅拷贝
————————————————
浅(引用)拷贝:共用同一内存地址,你改值我也变
深(引用)拷贝:深拷贝即创建新的内存地址保存值(互不影响)
let hd = {
a: 1,
b: 2
};
let aa = {
f: "22",
e: {
name: "ssh",
age: 33
}
}
hd = Object.assign(hd, aa);
console.log(hd); //{a: 1, b: 2, f: "22", e: {…}}
console.log(hd.e === aa.e); //true 浅复制 只是复制了指针
console.log(aa);//{f: "22", e: {…}}
let arr1 = [1, 2, 3, 4, 56, 65, 3, 67],
arr2 = [2, 3, 6, 8, 3]
let arr3 = Object.assign(arr1, arr2) // [2, 3, 6, 8, 3, 65, 3, 67]
Object.assig会覆盖重复属性
let a,res
a={id:"1"}
res = Object.assign(a,{id:"2",name1:"aa"},{id:"2",name2:"bb"})
console.log(res) //{id: "2", name1: "aa", name2: "bb"}
Object.assig如果赋值期间出错,会终止退出,抛出错误 所以可能只会复制部分;
let aa = {}
let src = {
a: 'aa',
b: "bb",
get b() {
throw new Error();
},
c: "ccc"
}
try {
Object.assign(aa, src)
} catch (e) {
console.log(e);
console.log(aa);
}
对象标识及相等判定
在 ECMAScript 6 之前,有些特殊情况即使是===操作符也无能为力:
// 这些是===符合预期的情况
console.log(true === 1); // false
console.log({} === {}); // false
console.log("2" === 2); // false
// 这些情况在不同 JavaScript 引擎中表现不同,但仍被认为相等
console.log(+0 === -0); // true
console.log(+0 === 0); // true
console.log(-0 === 0); // true
// 要确定 NaN 的相等性,必须使用极为讨厌的 isNaN()
console.log(NaN === NaN); // false
console.log(isNaN(NaN)); // true
为改善这类情况,ECMAScript 6 规范新增了 Object.is(),这个方法与===很像,但同时也考虑
到了上述边界情形。这个方法必须接收两个参数:
console.log(Object.is(true, 1)); // false
console.log(Object.is({}, {})); // false
console.log(Object.is("2", 2)); // false
// 正确的 0、-0、+0 相等/不等判定
console.log(Object.is(+0, -0)); // false
console.log(Object.is(+0, 0)); // true
console.log(Object.is(-0, 0)); // false
// 正确的 NaN 相等判定
console.log(Object.is(NaN, NaN)); // true
要检查超过两个值,递归地利用相等性传递即可:
function recursivelyCheckEqual(x, ...rest) {
return Object.is(x, rest[0]) &&
(rest.length < 2 || recursivelyCheckEqual(...rest));
}