JavaScript之深拷贝&浅拷贝
深拷贝&浅拷贝,说起来都明白,但是说不出所以然。今天就系统的整理下思绪,一点点的将其分析出所以然
废话不多说
浅拷贝
简单的说就是一个值引用,学生时代接触过编程的人都应该了解过指针,浅拷贝可以说就是变量拷贝的是数据的地址而不是数据本身,所以从直观上看来,好像是一个数据改变了, 所有数据都改变了
var obj1 = {
str: "good"
}
var obj2 = obj1;
console.log(obj2.str); //good
obj2.str = "bad";
console.log(obj1.str); //bad

通过浅拷贝 A 和 B 指向相同的内存地址,通过 A (或 B)对数据进行修改,相应的在 B (或 A)可以得到体现
那么就 JavaScript 中来说,浅拷贝一般是指数组对象的浅拷贝,因为基本数据类型的赋值都是值传递(所以深拷贝都是一层一层的拨开对象或数组,直到基本数据类型然后进行赋值拷贝,完成)
function copy(obj) {
var cc = {};
for(var i in obj) {
cc[i] = obj[i];
}
return cc;
}
var obj1 = {
name: "yellow",
arr: ["北京", "上海", "广州"]
}
var obj2 = copy(obj1);
obj2.name = "blue";
obj2.arr.push("深圳");
此时,对象 obj1 和 obj2 的如下图所示, 可以看到属性 name 的值是不一样的,但是属性 arr 由于是一个数组,两个对象里都多了一个“深圳”,因为他们都是一个值引用, 两个对象里的arr 指向同一块内存地址,所以通过其中一个改变其值,另一个的值也会跟着改变。这是一个非常常见的一个浅拷贝的例子。

到这里,我们可以总结一下:浅拷贝,对于基本数据类型是值传递,而对于引用类型(对象等)是进行的引用传递。
深拷贝
深拷贝,从字面看,就是比浅深一点。
深拷贝与浅拷贝从我们直观测试看得到的地方来说,区别就是:深拷贝之后,两个值的变化互不影响
怎样达到这个目的呢?就是在拷贝的时候,是把值传递出去,还不是单纯的指向值的位置,就像上边的 name 值一样。
可以对比下上边两段代码的 str 属性和 name 属性,发现了什么么。在第一段代码中 str 属性是放在对象 obj1 里边进行的赋值,是以对象 obj1 为单位的,第二段代码中,name 属性是以name 属性本身为单位的赋值,name 本身是一个字符串类型(基本数据类型),所以进行的是值传递。
所以, 如果在进行赋值拷贝时,如果一个值是引用类型(对象), 那么就“刨”一层,直到遇到基本数据类型,然后进行赋值。从而使整个拷贝都是基于基本数据类型进行的,最终达到我们深拷贝的结果
上一段简单的深拷贝示例代码
function deepCopy(obj) {
if(typeof obj !== "object" && obj === null) {
return;
} else {
var cc = obj.constructor === Array?[]:{};
}
for(var i in obj) {
if(typeof obj[i] === "object") {
cc[i] = deepCopy(obj[i]);
} else {
cc[i] = obj[i];
}
}
return cc;
}
以上是个人对深拷贝&浅拷贝的理解,欢迎交流点评。
JavaScript之深拷贝&浅拷贝的更多相关文章
- javascript对象深拷贝,浅拷贝 ,支持数组
javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...
- JavaScript实现深拷贝(深复制) 面试题
1.两种方法实现深拷贝(深复制) (1)方法一:兼容性好,请仔细看代码(网上大部分代码有Bug) (2)方法二:需要对象满足JSON数据格式.JOSN数据格式:http://www.cnblogs.c ...
- JS Object Deep Copy & 深拷贝 & 浅拷贝
JS Object Deep Copy & 深拷贝 & 浅拷贝 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Refe ...
- c# 内存的具体表现- 通用类型系统 深拷贝 浅拷贝 函数传参
c# 通用类型系统 及变量在 深拷贝 浅拷贝 函数传参 中的深层次的表现 在编程中遇到了一些想不到的异常,跟踪发现,自己对于c#变量在内存上的表现理解有偏差,系统的学习并通过代码实验梳理了各种情况下, ...
- python集合增删改查,深拷贝浅拷贝
集合 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系 ...
- 【opencv】imread 赋值 深拷贝浅拷贝
import cv2 import copy import os def filter_srcimg(dstimg): ss=3 srcimg=copy.deepcopy(dstimg) #aa=5 ...
- Java基础 深拷贝浅拷贝
Java基础 深拷贝浅拷贝 非基本数据类型 需要new新空间 class Student implements Cloneable{ private int id; private String na ...
- 【04】Python 深拷贝浅拷贝 函数 递归 集合
1 深拷贝浅拷贝 1.1 a==b与a is b的区别 a == b 比较两个对象的内容是否相等(可以是不同内存空间) a is b 比较a与b是否指向同一个内存地址,也就是a与b的id是否相 ...
- JavaScript中深拷贝实现
JavaScript 中深拷贝实现 拷贝时候涉及到: 1.循环结构 2.判断数组 Array 还是对象 Object 函数实现 /** * 获取满足条件的数组中的第一个元素 * @param ...
随机推荐
- 常用 Math 属性及方法
Math 对象 Math.PI π 3.141592653589793 Math.ceil('2.5') Math.ceil(2.1) 向上取整 3 Math.floor ...
- js 面试题总结 3
console.log(a); // undefined function fn() { console.log(a); // undefined } fn(); console.log(a); 创建 ...
- Vue 组件设计
Vue 组件设计 Vue 作为 MVVM 框架一员,不管是写业务还是基础服务,都少不了书写组件.本文总结一下书写业务组件的一些心得. 为什么要写组件? 我们知道,只要是组件,就需要在引用的时候与 vi ...
- 动态规划-House Robber
2018-04-29 20:20:56 House Robber问题是leetcode上经典的系列题,这里对其中的题目做一个讲解. 198. House Robber 问题描述: 问题求解: 本质上就 ...
- C#通过WMI读取MAC地址
该方法依赖WMI的系统服务,该服务一般不会被关闭;但如果系统服务缺失或者出现问题,该方法无法取得MAC地址,需要重启Windows Management Instrumentation服务. publ ...
- <p>1、查询端口号占用,根据端口查看进程信息</p>
2017年6月份的时候,我就着手在公司推广git,首先我自己尝试搭建了GitLab来管理代码,并且通过以下博客记录了GitLab的搭建,以及GitLab备份,GitLab升级等事情. git学习——& ...
- STM32知识点纪要
1.GPIO BSRR(端口位设置寄存器)是赋1相应IO拉高,赋0无影响 BRR(端口位清除寄存器)是是赋1相应IO拉低,赋0无影响 2.UART 连线TX—TX,RX—RX 3.JTAG和SWD接口 ...
- SharePoint Development - Custom List using Visual Studio 2010 based SharePoint 2010
博客地址 http://blog.csdn.net/foxdave 之前两次我们定义了内容类型和字段,我们现在用它们为这一讲服务--创建一个自定义列表. 打开Visual Studio,打开之前的工程 ...
- JS在项目中用到的AOP, 以及函数节流, 防抖, 事件总线
1. 项目中在绑定事件的时候总想在触发前,或者触发后做一些统一的判断或逻辑,在c#后端代码里,可以用Attribute, filter等标签特性实现AOP的效果,可是js中没有这种用法,归根到本质还是 ...
- Http协议——Header说明
下图是我用IE的开发人员工具截取的一个Http Request请求的Header. 下图是我用IE的开发人员工具截取的一个Http Response的Header. header常用指令 header ...