JS中,一般的赋值传递的都是对象/数组的引用,并没有真正的深拷贝一个对象,如何进行对象的深拷贝呢?

var a = {name : 'miay'};
var b = a;
b.name = 'Jone';
console.log(a.name) //Jone

上述代码中,b指向a所指向的栈对象,也就是说a,b指向同一个栈对象,这种属于对象的浅拷贝。

var a = {name : 'miay'};
var b = Object.assign({},a);
console.log(a === b) //false
b.name = 'chris';
console.log(a.name) //miya

上述代码将原对象拷贝到一个空对象中,a,b指向的是不同的栈对象,所以对b.name重新赋值不会影响到a.name,但是如果a.name是一个对象的引用,而不是一个字符串,那么a.nam和b.name指向的栈空间就是同一个了,看下面的栗子:

var a = {name:{firstName:"tang",lastName:"jiao"}}
var b = Object.assign({},a)
console.log(a === b); //false
b.name.firstName = "chen"
console.log(a.name.firstName) //chen

可以看出,Object.assign只是介于对象的深克隆和浅克隆之间的一种拷贝。具体来说也只是浅拷贝。对于对象属性值为引用类型时,赋值时也是对于栈对象的引用罢了,那如何真正的进行对象的深拷贝呢?

使用JSON.parse()和JSON.stringify()对对象进行深拷贝

var clone = function(obj){
return JSON.parse(JSON.stringify(obj));
}
var a = {
a:function(){console.log('hello world')},
b:{c:1},
c:[1,2,3],
d:'tang',
e:new Date(),
f:null,
g:undefined
}
var b = clone(a);
console.log(b)

可以看出,上述clone的方法会忽略function和undefined的字段,对date类型支持貌似也不友好。而且只能克隆原始对象自身的值,不能克隆它继承的值,参考代码如下:

function Person(name){
this.name = name;
}
var tang = new Person('miya');
var newtang = clone(tang)
tang.constructor === Person //true
newtang.constructor === Person //false
console.log(newtang.constructor) //ƒ Object() { [native code] }

结论:对于纯数据的json对象的深克隆,可以使用JSON.parse()和JSON.stringify()方法,自己可以写个兼容function,undefined,继承,Date的深拷贝的方法:

var clone = function(obj){
if(obj === null) return null;
if(obj.constructor !== 'object') return obj;
if(obj.constructor === Date) return new Date(obj);
if(obj.constructor === RegExp) return new RegExp(obj);
var newObj = new obj.constructor(); //保持继承的原型
for(var key in obj){
if(obj.hasOwnProperty(key)){
var val = obj[key];
newObj[key] = typeof val === 'object' ? arguments.callee(val):val;
}
}
return newObj;
}

经过验证,上述的原型的继承,还是function,undefined,日期,正则等都完美实现深拷贝!

这里运用的就是建立一个新的对象,进行原始对象自有属性的拷贝,遇到引用类型则继续该方法的执行,非引用类型直接赋值。

我唯一知道的就是自己的无知。【完】

【我所知道的只有一件事,那就是我什么也不知道。】 ——苏格拉底

[BGM] The Old Measure  ——Daniel Martin Moore

最新文章

  1. A B-tree index can be used for column comparisons in expressions that use the =, >, >=, <, <=, or BETWEEN operators.
  2. Ubuntu快捷键
  3. js实现svg图形转存为图片下载
  4. ServiceStack.OrmLite 学习笔记3 建表
  5. 正则表达式中的\b
  6. hdu 2094 产生冠军(STL,set)
  7. 记录一下JS正则的坑
  8. Linux route命令详解和使用示例(查看和操作IP路由表)
  9. ThinkPHP 中使用 PHPMailer 发送邮件 支持163和QQ邮箱等
  10. Sicily-1063
  11. ubuntu 12.04 安装sublime2
  12. mysql 创建表 create table详解
  13. oracle闪回技术总结之闪回数据库
  14. 为异常处理做准备,熟悉一下WinDbg工具
  15. git的基本应用(一)
  16. L1与L2正则(转)
  17. CEditUI 控件使用
  18. Nginx 工作原理
  19. 关于Java按键事件KeyEvent重点几步
  20. ADO.Net 综合练习题

热门文章

  1. JavaScript 简介与语法
  2. Qt 编译出现 error LNK2019: 无法解析的外部符号
  3. [LC] 328. Odd Even Linked List
  4. OpenCV Laplace 算子
  5. t-检验
  6. spring整合ehcache实现缓存
  7. spring+mybatis+mysql5.7实现读写分离,主从复制
  8. react-native start 启动错误解决方法
  9. win10 64位 安装JDK1.8
  10. GDB调试系列之了解GDB