博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js深拷贝和浅拷贝
阅读量:5141 次
发布时间:2019-06-13

本文共 2883 字,大约阅读时间需要 9 分钟。

一:浅拷贝

var m = { a: 10, b: 20 }
var n = m;
n.a = 15;
//m.a会输出15,因为这是浅拷贝,n和m指向的是同一个堆,对象复制只是复制的对象的引用。

实现方式

function simpleClone(initalObj) {

var obj = {};
for ( var i in initalObj) {
obj[i] = initalObj[i];
}
return obj;
}

Object.assign()实现

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目

标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身

var obj = { a: {a: "hello", b: 21} };

var initalObj = Object.assign({}, obj);

initalObj.a.a = "changed";

console.log(obj.a.a); // "changed"

一:深拷贝

var m = { a: 10, b: 20 }

var n = {a:m.a,b:m.b};
n.a = 15;

这次,我们再来输出m.a ,发现m.a的值还是10,并没有改变,m对象和n对象是虽然所有的值都是

一样的,但是在堆里面,对应的不是同一个了,这个就是深拷贝。

实现方式

当object只有一层的时候,是深拷贝

var obj1 = { a: 10, b: 20, c: 30 };

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

多层时:

var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};

用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。

可以封装如下函数

var cloneObj = function(obj){

var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};

 

递归拷贝

 

function deepClone(initalObj, finalObj) {

var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : {};
arguments.callee(prop, obj[i]);
} else {
obj[i] = prop;
}
}
return obj;
}
var str = {};
var obj = { a: {a: "hello", b: 21} };
deepClone(obj, str);
console.log(str.a);

 

使用Object.create()方法

直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。

function deepClone(initalObj, finalObj) {

var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a =
initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
} else {
obj[i] = prop;
}
}
return obj;
}

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

另外一个很热门的函数库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

 

转载于:https://www.cnblogs.com/liuzhouyuan/p/9228293.html

你可能感兴趣的文章
如何自绘树形控件(QQ好友列表)
查看>>
web异步开发——ajax
查看>>
通过修改VHD文件的位置来提升性能
查看>>
将WPF版的弹幕播放器给优化了一下
查看>>
Qt5 动态库的创建与使用
查看>>
面向对象设计
查看>>
Sqoop迁移Hadoop与RDBMS间的数据
查看>>
[label][JavaScript]读nowmagic - js词法作用域、调用对象与闭包
查看>>
模板模式
查看>>
PAT 1014 福尔摩斯的约会
查看>>
ssh2整合中的一些问题
查看>>
hibernate Expression详解
查看>>
LeetCode #303. Range Sum Query
查看>>
oracle 自增序列实现 可作为主键
查看>>
STM32----stlink口
查看>>
Android viewpager切换到最后一页时,跳转至其他activity
查看>>
开启GD拓展
查看>>
JQUERY 大于
查看>>
ZooKeeper做独立server执行(上)
查看>>
《经济地理与企业兴衰》学习笔记
查看>>