1. 对于基本数据类型

其值在内存中占据着固定大小的空间,并被保存在栈内存中。当一个变量向另一个变量复制基本类型的值,会创建这个值的副本,并且我们不能给基本数据类型的值添加属性。其为深拷贝。

2. 对于引用类型

 浅拷贝:只复制指向某个对象的指针,而不复制对象本身,新旧对象共享一块内存; 改变一个对象,另一个会随之改变;
 深拷贝:复制并创建一个一模一样的对象,不共享内存,修改新对象,旧对象保持不变。

01 浅拷贝的实现

var arr = [1, 2, 3, '4'];

var arr2 = arr;
arr2[1] = "test";
console.log(arr); // [1, "test", 3, "4"]
console.log(arr2); // [1, "test", 3, "4"]

我们可以看到,简单的赋值便是浅拷贝,一个对象改变,另一个也随之改变。

02 深拷贝的实现

1.使用JSON.stringfy();

var obj1 = { a: { b: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.a.b = 20;
console.log(obj1); //{ a: { b: 10 } }
console.log(obj2); //{ a: { b: 20 } }
console.log(obj1 === obj2); // false
console.log(obj1.a === obj2.a); // false

2.使用递归实现

function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
return objClone;
}
let a=[1,2,3,4],
b=deepClone(a);
a[0]=2;
console.log(a);//[2, 2, 3, 4]
console.log(b);// [1, 2, 3, 4]

当对象中有循环引用时:

即:

var a={c:1,d:2};
a.e=a;

设置一个标记,当目前对象已经被克隆过时,则不再循环调用

function deepClone(obj){
mark[obj]=1;
let objClone = Array.isArray(obj)?[]:{};
for(key in obj){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
if(mark[obj[key]]==1){
objClone[key]=obj[key];
continue;
}
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
return objClone;
}
var a={c:1,d:2};
a.e=a;
mark={};
b=deepClone(a); console.log(a);//{c: 1, d: 2, e: {…}}
console.log(b);//{c: 1, d: 2, e: {…}}

3.JQuery的extend()。

$.extend( [deep ], target, object1 [, objectN ] )

deep表示是否深拷贝,true为深拷贝,false为浅拷贝;

target object类型 目标对象,其他对象的成员属性将被附加到该对象上。

object1  objectN可选。 Object类型 第一个以及第N个被合并的对象。

let a=[0,1,[2,3],4],
b=$.extend(true,[],a);
a[0]=-1;
a[2][0]=-1;
console.log(a);//[-1,1,[-1,3],4]
console.log(b);//[0,1,[2,3],4]

特别说明:concat(),slice()不是深拷贝,因为其只是一级属性是深拷贝,二级属性就不是了。

let a=[0,1,[2,3],4],
b=a.slice();
a[0]=-1;
a[2][0]=-1;
console.log(a);//[-1,1,[-1,3],4]
console.log(b);//[0,1,[-1,3],4]
let a=[0,1,[2,3],4],
b=[].concat(a);
a[0]=-1;
a[2][0]=-1;
console.log(a);//[-1,1,[-1,3],4]
console.log(b);//[0,1,[-1,3],4]

js深拷贝与浅拷贝的区别及实现的更多相关文章

  1. 关于JS深拷贝和浅拷贝

    最近在前端开发中遇到一些问题,就是数组中的某个对象或某个对象的值改变之后,在不刷新页面的时候需要重新渲染值时,页面显示的还是原来的数据.比如: data{ A:[{id:1,num:1},{id:2, ...

  2. js 深拷贝和浅拷贝

    js 深拷贝和浅拷贝 先举一下项目中遇到的两个例子: 例子1: var json = $.parseJSON(data.data);//data.data是接口返回的值var a = json.cha ...

  3. 老生常谈之js深拷贝与浅拷贝

    前言 经常会在一些网站或博客看到"深克隆","浅克隆"这两个名词,其实这个很好理解,今天我们就在这里分析一下js深拷贝和浅拷贝. 浅拷贝 我们先以一个例子来说明 ...

  4. Python 深拷贝和浅拷贝的区别

    python的复制,深拷贝和浅拷贝的区别    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用  ...

  5. js 中引用类型 的深拷贝 和 浅拷贝的区别

    一.曾经在读JQ源码的时候,对深拷贝算是有了一点的理解.我们在项目中是不是经常会遇到这样的问题呢? 后台返回一个数组对象(引用类型).次数在页面渲染中需要对部分数据进行处理 比如:银行卡6234509 ...

  6. Python赋值语句与深拷贝、浅拷贝的区别

    参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...

  7. python深拷贝和浅拷贝的区别

    首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别. 什么是可变对象,什么是不可变对象: 可变对象 ...

  8. 在vue中子组件修改props引发的对js深拷贝和浅拷贝的思考

    不管是react还是vue,父级组件与子组件的通信都是通过props来实现的,在vue中父组件的props遵循的是单向数据流,用官方的话说就是,父级的props的更新会向下流动到子组件中,反之则不行. ...

  9. c# 深拷贝与浅拷贝的区别分析及实例

    浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. 深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的. 深拷贝是指源对象与拷贝对象互相独 ...

随机推荐

  1. 关于js的值传递和引用传递

    最近在弄一个东西,明明就很简单的.不知道为啥有个坑,双向绑定,不过当有个数组为空时,它不会发送空的数组,而是不发送.这就坑爹了.导致老是删不掉. 处理了下,改成验证为空时,发送'[]‘字符串.成功.但 ...

  2. 类的加载、时机、反射、模板设计、jdk7/jdk8新特性(二十六)

    1.类的加载概述和加载时机 * A:类的加载概述 * 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. * 加载 * 就是指将class文 ...

  3. ES6 解构赋值的常见用途,很强大

    字符串 var [a,b,c,d,e] = "hello"; console.log(a); // h console.log(b); // e console.log(c); / ...

  4. 一步一步学Silverlight 2系列(9):使用控件模板

    述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  5. Nth prime & numbers of primes (模板)

    都是取的模板,这几天做的素数题挺多的,所以整理了放在这里,感觉有一天回用到的! SPOJ:Nth Prime:     求第N个素数,N<1e9. #include<bits/stdc++ ...

  6. BZOJ_1563_[NOI2009]诗人小G_决策单调性

    BZOJ_1563_[NOI2009]诗人小G_决策单调性 Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超 ...

  7. 【NOIP 2003】 加分二叉树

    [题目链接] 点击打开链接 [算法] 树形DP即可 [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 50 in ...

  8. C++ set和map的简单使用

    C++中的STL模板库的功能可谓相当强大.今天我们来简单说一下set和map的使用方法. 1.pair 我们先来说一下pair.pair定义在头文件<utility>中,其本身相当于一个已 ...

  9. 微信小程序服务类目大坑:特殊行业服务类目所需资质材料

    作为一个技术开发人员,遇到特殊行业服务类目所需资质材料,只能叫苦连天了,妈的,这个不是技术可以解决的问题,如果技术可以解决的问题都不是问题. 百牛信息技术bainiu.ltd整理发布于博客园 特殊行业 ...

  10. 一个C#文件传输模块,支持断点续传

    一个C#文件传输模块,支持断点续传 最近做一个程序需要传送文件,在网上找了好久也没找到好用的方案,于是自己写了一个,与大家分享,希望大家帮忙改进,拍砖欢迎-文件采取分块发送,每块单独校验,能够保证文件 ...