Skip to content
This repository has been archived by the owner on Feb 9, 2021. It is now read-only.

JavaScript 中深拷贝(开辟新的内存存储)对象的方法 #9

Open
lbwa opened this issue Apr 18, 2018 · 0 comments
Open
Labels
Pure JS Pure JavaScript .etc

Comments

@lbwa
Copy link
Owner

lbwa commented Apr 18, 2018

拷贝方法的分类

深拷贝:开辟新的内存存储数据。
浅拷贝:没有开辟新的内存存储数据,仅仅复制指向数据的指针。

常用拷贝方法

  1. Object.assign(目标对象,要拷贝的对象)。
    注:当要拷贝的对象属性中存在引用(即对象的某个属性值是对象)时,仅仅复制引用(指针),此时针对此引用是浅拷贝,而不是深拷贝。

  2. 拓展运算符

Object.assign(obj0,obj1, obj2) 相同,后面的对象属性会覆盖前面的对象同名属性。

const obj = {...{ num: 10 }, ...{ num:20 }, ...{ num:30 }}
obj // { num: 30 }
  1. for...of 循环 Object.keys 和 Object.values ,其中 Object.keys(要拷贝的对象)得到所有键名组成的数组,Object.values(要拷贝的对象)得到所有键值组成的数组。

注:一般情况下不能直接使用 for..of 来遍历对象,除非部署 Iterator 接口。最佳实践是与 Object.keys() 搭配使用。

for (let key of Object.keys(someObject)) {
  console.log(key + ': ' + someObject[key]);
}

for...of 的类似循环 for...in 循环可用于遍历对象的键名,但是它也会枚举原型链上的属性,Object.keys 只枚举对象本身的属性

  1. JSON.parse(JSON.stringify(要拷贝的对象))——最简单的方法,但无法复制函数属性,会破坏原型链

  2. jQuery.extend(是否深拷贝,要拷贝的对象)

其中,特别注意的是 1,2 都是对对象的浅复制,即在被复制的对象中有指向另外的对象的指针,那么将会复制该指针!!

拓展:属性键名的遍历方法

ES6 一共有 5 种方法可以遍历对象的属性。

  1. for...in
    for...in 循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

  2. Object.keys(obj)
    Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

  3. Object.getOwnPropertyNames(obj)
    Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

  4. Object.getOwnPropertySymbols(obj)
    Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

  5. Reflect.ownKeys(obj)
    Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

  • 首先遍历所有数值键,按照数值升序排列。
  • 其次遍历所有字符串键,按照加入时间升序排列。
  • 最后遍历所有 Symbol 键,按照加入时间升序排列。

参考

ECMAScript 6入门

@lbwa lbwa added the Pure JS Pure JavaScript .etc label Apr 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Pure JS Pure JavaScript .etc
Projects
None yet
Development

No branches or pull requests

1 participant