js中的深拷贝和浅拷贝2
//浅复制
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的更多相关文章
- js 中的深拷贝与浅拷贝
在面试中经常会问到js的深拷贝和浅拷贝,也常常让我们手写,下面我们彻底搞懂js的深拷贝与浅拷贝. 在js中 Array 和 Object 这种引用类型的值,当把一个变量赋值给另一个变量时,这个值得副 ...
- js中的深拷贝与浅拷贝
对象的深拷贝于浅拷贝 对于基本类型,浅拷贝过程就是对值的复制,这个过程会开辟出一个新的内存空间,将值复制到新的内存空间.而对于引用类型来书,浅拷贝过程就是对指针的复制,这个过程并没有开辟新的堆内存空间 ...
- js 中的 深拷贝与浅拷贝
js在平时的项目中,赋值操作是最多的:比如说: var person1 = { name:"张三", age:18, sex:"male", height:18 ...
- JS中的深拷贝和浅拷贝
浅拷贝 浅拷贝是拷贝第一层的拷贝 使用Object.assign解决这个问题. let a = { age: 1 } let b = Object.assign({}, a) a.age = 2 co ...
- JS对象复制(深拷贝、浅拷贝)
如何在 JS 中复制对象 在本文中,我们将从浅拷贝(shallow copy)和深拷贝(deep copy)两个方面,介绍多种 JS 中复制对象的方法. 在开始之前,有一些基础知识值得一提:Javas ...
- javascript中的深拷贝与浅拷贝
javascript中的深拷贝与浅拷贝 基础概念 在了解深拷贝与浅拷贝的时候需要先了解一些基础知识 核心知识点之 堆与栈 栈(stack)为自动分配的内存空间,它由系统自动释放: 堆(heap)则是动 ...
- 浅谈Java中的深拷贝和浅拷贝(转载)
浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...
- C语言中的深拷贝和浅拷贝
//C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #inc ...
- 浅谈Java中的深拷贝和浅拷贝
转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...
随机推荐
- Spark-内存管理调优
这篇文章主要是对官网内容学习过程的总结,大部分是原文,加上自己的学习笔记!!! spark 2.0+内存模型 调优内存使用时需要考虑三个因素: 对象使用的内存数量(您可能希望您的整个数据集都能装入内存 ...
- Activiti 接收任务活动
流程中往往需要特定人接受任务并进行一定操作才能继续进行下去. 代码如下 import java.io.InputStream; import org.activiti.engine.ProcessEn ...
- [转]Visual Studio 2010单元测试(2)--运行测试并查看代码覆盖率
Visual Studio 2010 单元测试--运行测试并查看代码覆盖率 运行测试并查看代码覆盖率对程序集中的代码运行测试时,可以通过收集代码覆盖率数据来查看正在测试的项目代码部分. 运行测试并查看 ...
- Python pylint的安装和使用
Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准和有潜在问题的代码. Pylint 是一个 Python 工具,除了平常代码分析工具的作用之 ...
- ajaxfileupload 上传使用demo
1.添加js引用 <script src="JS/jquery-1.4.2.min.js" type="text/javascript"></ ...
- SQL server插入数据后,获取自增长字段的值
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 insert into Tb_People(uname,er ...
- gitlab merge request
分支提了mr之后, 又有commit 不用重新提mr,mr中会自动更新 要保证项目下的.git目录中有hooks这个目录(如果是从github迁移到gitlab的项目, 可能没有这个目录, 导致mr不 ...
- 原生JS实现动态时钟(优化)
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- WPF DataGrid动态生成列的单元格背景色绑定
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.DisplayInde ...
- KOA 学习(一)
一.安装KOA 用npm下载KOA 就会在koa文件夹下生成 二.输出hello,world 我下载的KOA版本号是2.0.1 const Koa = require('koa'); const ap ...