js深拷贝与浅拷贝的区别及实现
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深拷贝与浅拷贝的区别及实现的更多相关文章
- 关于JS深拷贝和浅拷贝
最近在前端开发中遇到一些问题,就是数组中的某个对象或某个对象的值改变之后,在不刷新页面的时候需要重新渲染值时,页面显示的还是原来的数据.比如: data{ A:[{id:1,num:1},{id:2, ...
- js 深拷贝和浅拷贝
js 深拷贝和浅拷贝 先举一下项目中遇到的两个例子: 例子1: var json = $.parseJSON(data.data);//data.data是接口返回的值var a = json.cha ...
- 老生常谈之js深拷贝与浅拷贝
前言 经常会在一些网站或博客看到"深克隆","浅克隆"这两个名词,其实这个很好理解,今天我们就在这里分析一下js深拷贝和浅拷贝. 浅拷贝 我们先以一个例子来说明 ...
- Python 深拷贝和浅拷贝的区别
python的复制,深拷贝和浅拷贝的区别 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 ...
- js 中引用类型 的深拷贝 和 浅拷贝的区别
一.曾经在读JQ源码的时候,对深拷贝算是有了一点的理解.我们在项目中是不是经常会遇到这样的问题呢? 后台返回一个数组对象(引用类型).次数在页面渲染中需要对部分数据进行处理 比如:银行卡6234509 ...
- Python赋值语句与深拷贝、浅拷贝的区别
参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...
- python深拷贝和浅拷贝的区别
首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别. 什么是可变对象,什么是不可变对象: 可变对象 ...
- 在vue中子组件修改props引发的对js深拷贝和浅拷贝的思考
不管是react还是vue,父级组件与子组件的通信都是通过props来实现的,在vue中父组件的props遵循的是单向数据流,用官方的话说就是,父级的props的更新会向下流动到子组件中,反之则不行. ...
- c# 深拷贝与浅拷贝的区别分析及实例
浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. 深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的. 深拷贝是指源对象与拷贝对象互相独 ...
随机推荐
- 计算机学院大学生程序设计竞赛(2015’12)01 Matrix
01 Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Swift语言学习(三)基础操作符
操作符是用于检测.更改或者组合值的特殊符号或短语.例如,加法操作符 (+) 将两个数字加到一起 (如 let i = 1 + 2).更复杂的例子包括逻辑与操作符 && (如 if en ...
- 【Java】DateUtil(1)
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...
- 基于jQuery仿淘宝产品图片放大镜特效
在开发商城的时候,往往会用到图片的放大功能,这里把自己在近期项目中使用的放大镜特效做一下总结(非插件). 放大镜效果 常用的js组件jquery.imagezoom,jquery.jqzoom,jqu ...
- 【Codeforces 20C】 Dijkstra?
[题目链接] 点击打开链接 [算法] dijkstra [代码] #include<bits/stdc++.h> using namespace std; typedef long lon ...
- wsdl 生成代码 WCF
具体方法: 打开Microsoft Visual Studio 2008->Visual Studio Tools->Visual Studio 2008 命令提示窗口. 输入:wsdl ...
- 一梦浮生2012 IOS高级进阶目录
一梦浮生2012 精通iphone的UI开发,能熟练操作复杂表视图,熟练使用图层技术, 可以自定义UI控件,使用类别扩展系统控件功能; 擅长通讯技术,熟悉各种通信协议,精通xml, json, 二进制 ...
- Sublime text 安装Package Control
Package Control 插件是一个方便 Sublime text 管理插件的插件,但因为 Sublime Text 3 更新了 Python 的函数,API不同了,导致基于 Python 开发 ...
- 【旧文章搬运】Windows内核常见数据结构(基本类型)
原文发表于百度空间,2008-7-23 ========================================================================== 学内核从基 ...
- servlet 3 文件上传
1.up.jsp <%@ page language="java" pageEncoding="utf-8"%> <form action=& ...