所谓 深浅拷贝
对于仅仅是复制了引用(地址),换句话说,复制了之后,原来的变量和新的变量指向同一个东西,彼此之间的操作会互相影响,为 浅拷贝
而如果是在堆中重新分配内存,拥有不同的地址,但是值是一样的,复制后的对象与原来的对象是完全隔离,互不影响,为 深拷贝
 
深浅拷贝 的主要区别就是:复制的是引用(地址)还是复制的是实例。
 //浅复制
function shallowCopy(src){
var dst = {};
for(var key in src){
if(src.hasOwnProperty(key)){
dst[key] = src[key];
}
}
return dst;
} var obj = {
a : 1,
arr : [2,3]
};
var shallowObj = shallowCopy(obj);
console.log(obj === shallowObj); //false
shallowObj.arr[1] = 5;
console.log(obj.arr[1]); // = 5
console.log(obj); //{ a: 1, arr: [ 2, 5 ] }
console.log(shallowObj); //{ a: 1, arr: [ 2, 5 ] }
//利用 递归 来实现深复制,对属性中所有引用类型的值,遍历到是基本类型的值为止。
function deepCopy(src){
if(!src && typeof src !== 'object'){
return;
}
var dst = src.constructor === Array ? []:{};
for(var key in src){
if(src.hasOwnProperty(key)){
if(src[key] && typeof src[key] === 'object'){
dst[key] = src[key].constructor === Array ? []:{};
dst[key] = deepCopy(src[key]); //递归
}else{
dst[key] = src[key];
}
}
}
return dst;
} var a = {
name:"jack",
age:20
};
var b = deepCopy(a);
console.log(a === b); //false
a.age = 30;
console.log(a); //{ name: 'jack', age: 30 }
console.log(b); //{ name: 'jack', age: 20 }

深拷贝浅拷贝问题探究:

1. Array 的 slice 和 concat 方法

两者都会返回一个新的数组实例。

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

看起来很像深拷贝,但实际上不是!!!

//slice
var a = [[1,2,3],4,5];
var b = a.slice();
console.log(a === b); //false
a[0][0] = 6;
console.log(a); //[ [ 6, 2, 3 ], 4, 5 ]
console.log(b); //[ [ 6, 2, 3 ], 4, 5 ] //concat
var a = [[1,2,3],4,5];
var b = a.concat(); //concat
console.log(b === a); //false
a[0][0] = 6;
console.log(a); //[ [ 6, 2, 3 ], 4, 5 ]
console.log(b); //[ [ 6, 2, 3 ], 4, 5 ]

Array的 slice 和 concat 方法 并不是 真正的深拷贝,他们其实是浅拷贝。   递归复制是无法完成的。

2. jQuery中的 extend 复制方法

可以用来扩展对象,这个方法可以传入一个参数:deep(true or false),表示是否执行深复制(如果是深复制则会执行递归复制)。

//jQuery环境下运行
//深复制
var obj = {
name:'xixi',
age:20,
company : { name : '腾讯', address : '深圳'}
};
var obj_extend = $.extend(true,{}, obj); //extend方法,第一个参数为true,为深拷贝,为false,或者没有为浅拷贝。
console.log(obj === obj_extend); //false
obj.company.name = "ali";
obj.name = "hei";
console.log(obj); //{name:'hei',age:20,company : { name : 'ali', address : '深圳'} }
console.log(obj_extend); //{name:'xixi',age:20,company : { name : '腾讯', address : '深圳'} }

//jQuery环境下运行
//浅复制
var obj = {
    name:"xixi",
age:20,
company : { name : '腾讯', address : '深圳'}
};
var obj_extend = $.extend(false,{}, obj); //extend方法,第一个参数为true,为深拷贝,为false,或者没有为浅拷贝。
console.log(obj === obj_extend); //false
obj.name = "heihei";
console.log(obj); //{name:'heihei',age:20,company : { name : '腾讯', address : '深圳'}
console.log(obj_extend); //{name:'xixi',age:20,company : { name : '腾讯', address : '深圳'}

总结:Array 的 slice 和 concat 方法 和 jQuery 中的 extend 复制方法,他们都会复制第一层的值,对于 第一层 的值都是 深拷贝,而到 第二层 的时候 Array 的 slice 和 concat 方法就是 复制引用 ,jQuery 中的 extend 复制方法 则 取决于 你的 第一个参数, 也就是是否进行递归复制。所谓第一层 就是 key 所对应的 value 值是基本数据类型,也就像上面栗子中的name、age,而对于 value 值是引用类型 则为第二层,也就像上面例子中的 company。

3. JSON 对象的 parse 和 stringify

JOSN 对象中的 stringify 可以把一个 js 对象序列化为一个 JSON 字符串,parse 可以把 JSON 字符串反序列化为一个 js 对象,这两个方法实现的是深拷贝

var obj = {
name:'xixi',
age:20,
company : { name : '腾讯', address : '深圳'}
};
var obj_json = JSON.parse(JSON.stringify(obj));
console.log(obj === obj_json); //false
obj.company.name = "ali";
obj.name = "hei";
console.log(obj); //{ name: 'hei', age: 20, company: { name: 'ali', address: '深圳' } }
console.log(obj_json); //{ name: 'xixi', age: 20, company: { name: '腾讯', address: '深圳' } }

js中的深拷贝和浅拷贝2的更多相关文章

  1. js 中的深拷贝与浅拷贝

    在面试中经常会问到js的深拷贝和浅拷贝,也常常让我们手写,下面我们彻底搞懂js的深拷贝与浅拷贝. 在js中 Array 和 Object  这种引用类型的值,当把一个变量赋值给另一个变量时,这个值得副 ...

  2. js中的深拷贝与浅拷贝

    对象的深拷贝于浅拷贝 对于基本类型,浅拷贝过程就是对值的复制,这个过程会开辟出一个新的内存空间,将值复制到新的内存空间.而对于引用类型来书,浅拷贝过程就是对指针的复制,这个过程并没有开辟新的堆内存空间 ...

  3. js 中的 深拷贝与浅拷贝

    js在平时的项目中,赋值操作是最多的:比如说: var person1 = { name:"张三", age:18, sex:"male", height:18 ...

  4. JS中的深拷贝和浅拷贝

    浅拷贝 浅拷贝是拷贝第一层的拷贝 使用Object.assign解决这个问题. let a = { age: 1 } let b = Object.assign({}, a) a.age = 2 co ...

  5. JS对象复制(深拷贝、浅拷贝)

    如何在 JS 中复制对象 在本文中,我们将从浅拷贝(shallow copy)和深拷贝(deep copy)两个方面,介绍多种 JS 中复制对象的方法. 在开始之前,有一些基础知识值得一提:Javas ...

  6. javascript中的深拷贝与浅拷贝

    javascript中的深拷贝与浅拷贝 基础概念 在了解深拷贝与浅拷贝的时候需要先了解一些基础知识 核心知识点之 堆与栈 栈(stack)为自动分配的内存空间,它由系统自动释放: 堆(heap)则是动 ...

  7. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  8. C语言中的深拷贝和浅拷贝

    //C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #inc ...

  9. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

随机推荐

  1. 事件处理器v-on:(event)/@(event)

    <!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...

  2. Struts2中param的作用

    1.页面传参与配置传参的区别:如果页面Form表单的参数在Action类中有相应的setter方法,则会优先取页面Form表单传过来的值,如果页面没有该属性同名的参数,则会从配置文件中取同名的参数值作 ...

  3. <Python基础>类和对象(初级)---烧开水的例子

    ''' 类:模板(模子) 类的名称:类名(人) 类的属性:一组数据(年龄,身高) 类的方法:进行操作的方法(走,跑,吃,喝) 对象:实体 类的抽象:把现实中的物品用类去表示 ''' #创建一个类 cl ...

  4. error C2440 “static_cast” 无法从“void (__thiscall C* )(void)...

    1.VC6中,说可以把函数在头文件中定义为:afx_msg void OnProgress()这样 但是在VS2005及以上,要求很严格,必须函数返回值为LRESULT类型,所以在VS2005及以上, ...

  5. 2019-5-21-dotnet-core-使用-CoreRT-将程序编译为-Native-程序

    title author date CreateTime categories dotnet core 使用 CoreRT 将程序编译为 Native 程序 lindexi 2019-05-21 11 ...

  6. 在AlexNet中LRN 局部响应归一化的理

    在AlexNet中LRN 局部响应归一化的理 一.LRN技术介绍: Local Response Normalization(LRN)技术主要是深度学习训练时的一种提高准确度的技术方法.其中caffe ...

  7. Leetcode953. Verifying an Alien Dictionary验证外星语词典

    某种外星语也使用英文小写字母,但可能顺序 order 不同.字母表的顺序(order)是一些小写字母的排列. 给定一组用外星语书写的单词 words,以及其字母表的顺序 order,只有当给定的单词在 ...

  8. Nginx的几个重要模块

    ngx_http_ssl_module 让Nginx可以支持HTTPS的模块,此模块下的大多数指令都应用在http,server上下文 ①ssl on | off; 是否开启ssl功能 ②ssl_ce ...

  9. JZOJ5966【NOIP2018提高组D2T3】保卫王国(并查集)

    题目 还是懒得把题目放上来了. 大意:给你一棵带点权的树,你要花费一些代价选择一些点使得相邻的两个点至少有一个被选. 然后有很多个询问,每个询问强制两个点的状态,问强制了这两个点的状态后的方案. 比赛 ...

  10. 【HAOI2015】树上染色—树形dp

    [HAOI2015]树上染色 [题目描述]有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得 ...