所谓 深浅拷贝
对于仅仅是复制了引用(地址),换句话说,复制了之后,原来的变量和新的变量指向同一个东西,彼此之间的操作会互相影响,为 浅拷贝
而如果是在堆中重新分配内存,拥有不同的地址,但是值是一样的,复制后的对象与原来的对象是完全隔离,互不影响,为 深拷贝
 
深浅拷贝 的主要区别就是:复制的是引用(地址)还是复制的是实例。
 //浅复制
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. OpenCASCADE动画功能2

    OpenCASCADE动画功能2 eryar@163.com OpenCASCADE是一个开发平台,主要提供三维曲面和实体建模.CAD数据交换及可视化等功能.OCCT最适用于开发三维建模CAD软件.加 ...

  2. Django之框架简介

    了解即可: 1.MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...

  3. vue 引入css及注意事项

    组件中: <style scoped> @import '../../static/css/xx.css'; // “ :”必须有 </style> 注:若用以下方法,全部组件 ...

  4. Tornado demo3 - tcpecho分析

    在这个demo中,主要是使用了Tornado中异步的TCP client和server来实现一个简单的echo效果(即客户端发送的message会从server端返回到client).代码的githu ...

  5. CAS企业级单点登录原理

    https://blog.csdn.net/anumbrella/article/details/80821486 1. 单点登录概述 1.1. 什么是单点登录? 单点登录:Single Sign O ...

  6. 【深度学习】CNN 中 1x1 卷积核的作用

    [深度学习]CNN 中 1x1 卷积核的作用 最近研究 GoogLeNet 和 VGG 神经网络结构的时候,都看见了它们在某些层有采取 1x1 作为卷积核,起初的时候,对这个做法很是迷惑,这是因为之前 ...

  7. 嘴巴题5 「BZOJ1864」[ZJOI2006] 三色二叉树

    1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1195 Solved: 882 [Submit][Status ...

  8. Leetcode240. Search a 2D Matrix II搜索二维矩阵2

    编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 matrix ...

  9. 【心无旁骛】vuex-typescript-example

    我不惮以最大的赞美去赞美这样的项目,真的是非常有创意又有能力. 先放上我喜欢的这个项目的开源地址:https://github.com/gluons/vuex-typescript-example 我 ...

  10. 刷屏的海底捞超级APP究竟是怎样与阿里云合作的

    海底捞正式发布了千人千面超级App已有两月,这家餐饮企业总能带给人们不一样的创新能力.谁能想到25年前从四川起家的火锅店,现在门店遍布国内近100座城市,已开门店超400家,海外门店也有50多家,全球 ...