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是同理 二级也是浅拷贝

————————————————
浅(引用)拷贝:共用同一内存地址,你改值我也变
深(引用)拷贝:深拷贝即创建新的内存地址保存值(互不影响)

  1. let hd = {
  2. a: 1,
  3. b: 2
  4. };
  5. let aa = {
  6. f: "22",
  7. e: {
  8. name: "ssh",
  9. age: 33
  10. }
  11. }
  12. hd = Object.assign(hd, aa);
  13. console.log(hd); //{a: 1, b: 2, f: "22", e: {…}}
  14. console.log(hd.e === aa.e); //true 浅复制 只是复制了指针
  15. console.log(aa);//{f: "22", e: {…}}
  16. let arr1 = [1, 2, 3, 4, 56, 65, 3, 67],
  17. arr2 = [2, 3, 6, 8, 3]
  18. let arr3 = Object.assign(arr1, arr2) // [2, 3, 6, 8, 3, 65, 3, 67]

Object.assig会覆盖重复属性

  1. let a,res
  2. a={id:"1"}
  3. res = Object.assign(a,{id:"2",name1:"aa"},{id:"2",name2:"bb"})
  4. console.log(res) //{id: "2", name1: "aa", name2: "bb"}

Object.assig如果赋值期间出错,会终止退出,抛出错误 所以可能只会复制部分;

  1. let aa = {}
  2. let src = {
  3. a: 'aa',
  4. b: "bb",
  5. get b() {
  6. throw new Error();
  7. },
  8. c: "ccc"
  9. }
  10. try {
  11. Object.assign(aa, src)
  12. } catch (e) {
  13. console.log(e);
  14. console.log(aa);
  15. }

对象标识及相等判定

在 ECMAScript 6 之前,有些特殊情况即使是===操作符也无能为力:

  1. // 这些是===符合预期的情况
  2. console.log(true === 1); // false
  3. console.log({} === {}); // false
  4. console.log("2" === 2); // false
  5. // 这些情况在不同 JavaScript 引擎中表现不同,但仍被认为相等
  6. console.log(+0 === -0); // true
  7. console.log(+0 === 0); // true
  8. console.log(-0 === 0); // true
  9. // 要确定 NaN 的相等性,必须使用极为讨厌的 isNaN()
  10. console.log(NaN === NaN); // false
  11. console.log(isNaN(NaN)); // true

为改善这类情况,ECMAScript 6 规范新增了 Object.is(),这个方法与===很像,但同时也考虑
到了上述边界情形。这个方法必须接收两个参数:

  1. console.log(Object.is(true, 1)); // false
  2. console.log(Object.is({}, {})); // false
  3. console.log(Object.is("2", 2)); // false
  4. // 正确的 0、-0、+0 相等/不等判定
  5. console.log(Object.is(+0, -0)); // false
  6. console.log(Object.is(+0, 0)); // true
  7. console.log(Object.is(-0, 0)); // false
  8. // 正确的 NaN 相等判定
  9. console.log(Object.is(NaN, NaN)); // true

要检查超过两个值,递归地利用相等性传递即可:

  1. function recursivelyCheckEqual(x, ...rest) {
  2. return Object.is(x, rest[0]) &&
  3. (rest.length < 2 || recursivelyCheckEqual(...rest));
  4. }