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. 计算机学院大学生程序设计竞赛(2015’12)01 Matrix

    01 Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. Swift语言学习(三)基础操作符

    操作符是用于检测.更改或者组合值的特殊符号或短语.例如,加法操作符 (+) 将两个数字加到一起 (如 let i = 1 + 2).更复杂的例子包括逻辑与操作符 && (如 if en ...

  3. 【Java】DateUtil(1)

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...

  4. 基于jQuery仿淘宝产品图片放大镜特效

    在开发商城的时候,往往会用到图片的放大功能,这里把自己在近期项目中使用的放大镜特效做一下总结(非插件). 放大镜效果 常用的js组件jquery.imagezoom,jquery.jqzoom,jqu ...

  5. 【Codeforces 20C】 Dijkstra?

    [题目链接] 点击打开链接 [算法] dijkstra [代码] #include<bits/stdc++.h> using namespace std; typedef long lon ...

  6. wsdl 生成代码 WCF

    具体方法: 打开Microsoft Visual Studio 2008->Visual Studio Tools->Visual Studio 2008 命令提示窗口. 输入:wsdl ...

  7. 一梦浮生2012 IOS高级进阶目录

    一梦浮生2012 精通iphone的UI开发,能熟练操作复杂表视图,熟练使用图层技术, 可以自定义UI控件,使用类别扩展系统控件功能; 擅长通讯技术,熟悉各种通信协议,精通xml, json, 二进制 ...

  8. Sublime text 安装Package Control

    Package Control 插件是一个方便 Sublime text 管理插件的插件,但因为 Sublime Text 3 更新了 Python 的函数,API不同了,导致基于 Python 开发 ...

  9. 【旧文章搬运】Windows内核常见数据结构(基本类型)

    原文发表于百度空间,2008-7-23 ========================================================================== 学内核从基 ...

  10. servlet 3 文件上传

    1.up.jsp <%@ page language="java" pageEncoding="utf-8"%> <form action=& ...