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,resa={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); // falseconsole.log({} === {}); // falseconsole.log("2" === 2); // false// 这些情况在不同 JavaScript 引擎中表现不同,但仍被认为相等console.log(+0 === -0); // trueconsole.log(+0 === 0); // trueconsole.log(-0 === 0); // true// 要确定 NaN 的相等性,必须使用极为讨厌的 isNaN()console.log(NaN === NaN); // falseconsole.log(isNaN(NaN)); // true
为改善这类情况,ECMAScript 6 规范新增了 Object.is(),这个方法与===很像,但同时也考虑
到了上述边界情形。这个方法必须接收两个参数:
console.log(Object.is(true, 1)); // falseconsole.log(Object.is({}, {})); // falseconsole.log(Object.is("2", 2)); // false// 正确的 0、-0、+0 相等/不等判定console.log(Object.is(+0, -0)); // falseconsole.log(Object.is(+0, 0)); // trueconsole.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));}
