对象

对象的扩展

对象的扩展运算符

  • 扩展运算符...应用场景
    • 解构赋值 ```javascript // 案例一:解构赋值 let { x, y, …z } = { x: 1, y: 2, a: 3, b: 4 }; x // 1 y // 2 z // { a: 3, b: 4 }

// 解构赋值是浅拷贝 let a = { foo: { bar: 1 } }

let b = { …a }; a.foo.bar = 5; b.foo.bar; // 5

// 可以正确拷贝set和get方法 let obj = { _val: 0, get val() { return this._val }, set val(val) { this._val = val } };

let test = { …obj }

test.val = 100 console.log(test.val); // 100 console.log(obj.val); // 0

  1. ```javascript
  2. // 案例二:错误的解构赋值
  3. // 解构赋值要求等号右边是一个对象
  4. let { ...z } = null; // 运行时错误
  5. let { ...z } = undefined; // 运行时错误
  6. // 解构赋值必须是最后一个参数,否则会报错
  7. let { ...x, y, z } = someObject; // 句法错误
  8. let { x, ...y, ...z } = someObject; // 句法错误
  1. // 扩展运算符的解构赋值,不能复制 那些从原型对象继承来的属性
  2. // 案例三
  3. let o1 = { a: 1 };
  4. let o2 = { b: 2 };
  5. o2.__proto__ = o1;
  6. /**
  7. * o2 = {
  8. * b: 2,
  9. * __proto__: { a: 1 }
  10. * }
  11. */
  12. let { ...o3 } = o2;
  13. o3 // { b: 2 }
  14. o3.a // undefined
  15. // 案例四
  16. const o = Object.create({ x: 1, y: 2 });
  17. o.z = 3;
  18. /**
  19. * o = {
  20. * z: 3,
  21. * __proto__: { x: 1, y: 2 }
  22. * }
  23. */
  24. let { x, ...newObj } = o;
  25. let { y, z } = newObj;
  26. x // 1 因为 x 是 直接解构赋值,所以能拿到
  27. y // undefined y 是 扩展对象得到newObj,然后再解构赋值,这时候newObj没有y属性
  28. z // 3
  29. newObj // { z: 3 }
  1. // 案例五:对象的扩展运算符
  2. let z = { a: 3, b: 4 };
  3. let n = { ...z };
  4. n // { a: 3, b: 4 }
  5. // 由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组
  6. let foo = { ...['a', 'b', 'c'] };
  7. foo // {0: "a", 1: "b", 2: "c"}
  8. {...{}, a: 1} // { a: 1 }
  9. // 如果扩展运算符后面不是对象,则会自动将其转为对象
  10. {...1} // 等同于 {...Object(1)} 结果是 {}
  11. {...true} // // 等同于 {...Object(true)} 结果是 {}
  12. {...undefined} // 等同于 {...Object(undefined)} 结果是 {}
  13. {...null} // 等同于 {...Object(null)} 结果是 {}
  14. // 如果扩展运算符后面是字符串,它会自动转成一个类似数组的对象
  15. {...'hello'} // {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
  1. // 案例六:拷贝对象的同时,拷贝其原型
  2. // 写法一的__proto__属性在非浏览器的环境不一定部署,因此推荐使用写法二和写法三
  3. // 写法一
  4. const clone1 = {
  5. __proto__: Object.getPrototypeOf(obj),
  6. ...obj
  7. };
  8. // 写法二
  9. const clone2 = Object.assign(
  10. Object.create(Object.getPrototypeOf(obj)),
  11. obj
  12. );
  13. // 写法三
  14. const clone3 = Object.create(
  15. Object.getPrototypeOf(obj),
  16. Object.getOwnPropertyDescriptors(obj)
  17. )