Object.assign()遇到的问题。

Object.assign(target, ...sources)

假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。例如:
var obj1 = {
a: 20,
b: {c: 2}
};
var copy = Object.assign({}, obj1);
此时,obj1.b 和 copy.b指向的还是一个同一个对象。

针对这种情况,有没有什么比较好的解决方案?

阅读 4.5k
4 个回答

Object.assign() 只是一级属性复制,比浅拷贝多深拷贝了一层

标准(安全)JSON格式的对象深拷贝可以用这个:const obj1 = JSON.parse(JSON.stringify(obj));

我从《你不知道的 JavaScript》一书看到,工具函数 JSON.stringify(..) 在将JSON对象序列化为字符串时也用到了 ToString 。请注意, JSON 字符串化并非严格意义上的强制类型转换,因为其中也涉及 ToString 的相 关规则。
对大多数简单值来说, JSON 字符串化和 果总是字符串:toString()的效果基本相同,只不过序列化的结

JSON.stringify( 42 ); // "42" 
JSON.stringify( "42" ); // ""42""(含有双引号的字符串)
JSON.stringify( null ); // "null" 
JSON.stringify( true ); // "true" 

所有 安全的 JSONJSON-safe)都可以使用 JSON.stringify(..) 字符串化。 安全的 JSON 值是指能够呈现为有效 JSON 格式的值。

下面敲黑板划重点:

为了简单起见, 我们来看看什么是 不安全的 JSON 值 。 undefinedfunctionsymbol (ES6+)和包含循环引用(对象之间相互引用,形成一个无限循环)的 对象 都不符合 JSON 结构标准,支持 JSON 的语言无法处理它们。

JSON.stringify(..) 在对象中遇到 undefinedfunctionsymbol 时会自动将其忽略, 在数组中则会返回 null (以保证单元位置不变)。

例如:

JSON.stringify( undefined ); 
JSON.stringify( function(){} ); 
JSON.stringify( [1,undefined,function(){},4] ); 
JSON.stringify({ a:2, b:function(){} } ); // undefined // undefined 
// "[1,null,null,4]" // "{"a":2}" 

对包含循环引用的对象执行 JSON.stringify(..) 会出错。

具体的深拷贝我们可以参考一下 jQuery 的实现。

具体细节实现可以参考这篇文章。

JavaScript专题之从零实现jQuery的extend

Object.assign只是浅拷贝,要用深拷贝可以用lodash的cloneDeep
cloneDeep
或者自己写一个遍历对象深度clone的方法,随便搜索都很多,就不贴代码了。

lodash的cloneDeep 或者 JSON.stringify() JSON.parse()转换一个新的对象得到的新对象就是会给分配一个新的内存空间

如果是单层操作,可以使用扩展运算

var copy = {...obj1};

如果不用合并操作的话,可以直接使用字符串互转即可

var copy = JSON.parse(JSON.stringify(obj1));
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏