JS深拷贝和浅拷贝

js中有一些基本数据类型,而对象就是像这样的{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他们的传值方式。
如果是基本类型传值,修改a并不会改变b的值

var a = 23;
var b = a;
b = 4;
console.log(b);
结果:4
console.log(a);
结果:23

但是对象就不同了,对象是按引用传值

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = obj1;
obj2.b = 100;
console.log(obj1);
结果:{ a: 10, b: 100, c: 30 } <-- b 被改到了
console.log(obj2);
结果:{ a: 10, b: 100, c: 30 }

要避免这样的事情发生的话就得按下面方法这样写

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 100;
console.log(obj1);
结果: { a: 10, b: 20, c: 30 } <-- b 沒被改到
console.log(obj2);
结果: { a: 10, b: 100, c: 30 }

这样就是深拷贝,这样不会修改原对象数据

JS深拷贝和浅拷贝_第1张图片
图1.jpeg

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
当然上面的方法比较傻瓜式,下面有两个简单的深拷贝方法:

  • jquery 有提供一个$.extend可以用来做 Deep Copy。
var $ = require('jquery');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);
结果:false
  • 另外一个很热门的函数库lodash,也有提供_.cloneDeep用来做 Deep Copy。
var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
结果:false

你可能感兴趣的