JavaScript的深拷贝与浅拷贝
深拷贝和浅拷贝是在面试中经常遇到的问题。今天在这里总结一下。
深拷贝与浅拷贝的问题,涉及到JavaScript的变量类型,先来说说变量的类型,变量类型包括基本类型和引用类型。
- 基本类型:Undefined,Null,Boolean,String,Number
- 引用类型:Array,Object,Date,RegExp,Function等
基本类型的变量直接按值存放在栈区里面,可以直接访问,比如我们平时把字符串、数字的值赋值给新变量,就是把值完全赋值过去,新变量的改变不会影响旧变量。
引用类型是存放在堆区的对象,变量在栈区中保存的是一个指针地址,指向真正保存在堆区中的对象。
浅拷贝
1.定义:浅复制只复制一层对象的属性。
- 针对对象中的基本类型是新开辟一块内存进行存储,改变新对象中的基本类型值不会影响原对象。
- 而对于对象中的引用类型,也会新开辟一块内存,不过这块内存,仅仅是用来存储对象中的引用类型的地址(即指针,这个指针还是指向存储在堆内存中的原对象)
先来看一段代码:下面这段代码只是浅复制
var obj = {
a:1,
arr: [2,3]
};
var shallowObj = shallowCopy(obj);
function shallowCopy(src){
var dst = {};
for(var prop in src){
if(src.hasOwnProperty(prop)){
dst[prop] = src[prop];
}
}
return dst;
}
console.log(shallowObj.a);//1
shallowObj.a = 3;
console.log(shallowObj.a);//3
console.log(obj.a);//1
console.log(shallowObj.arr);//[2,3]
shallowObj.arr[0] = 3;
console.log(shallowObj.arr);//[3,3]
console.log(obj.arr);//[3,3]

2.实现方式
- 可以通过es6新增的Object.assign来复制对象
let obj = {
name: "xiaoming",
hobby: [
"pinpong",
"soccer"
]
};
let copyObj = Object.assign({},obj);
copyObj.name = "xiaohong",
copyObj.hobby[0] = "jianzi";
console.log(obj);
console.log(copyObj);

- jQuery中的$.extend(,obj);Array.prototype.slice()和Array.prototype.concat()都会返回一个数组或者对象的浅拷贝。
深拷贝
1.定义:深拷贝不仅会将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上,这就不会存在上图中的obj和shallowObj的arr属性指向同一个对象的问题。
function cloneDeep(obj){
if(typeof obj !== 'object' || Object.keys(obj).length === 0 ){
return obj;
}
let resultData = {};
return recurison(obj, resultData);
}
function recurison(obj, data = {}){
for(key in obj){
if(typeof obj[key] == 'object' && Object.keys(obj[key].length > 0 )){
data[key] = recurison(obj[key]);
}else{
data[key] = obj[key];
}
}
return data;
}
var o1 = {
arr: [1, 2, 3],
obj: {
key: 'value'
},
func: function(){
return 1;
}
};
var o3 = cloneDeep(o1);
console.log(o3 === o1);//false
console.log(o3.obj === 01.obj);//false
console.log(o3.func === o1.func);//true

深拷贝对基本类型和引用类型都会新开辟一块内存来存储它们,需要注意的是,如果对象比较大,层级比较多,深复制会带来性能上的问题。所以在遇到深复制的情况时,可以考虑有没有其他替代的方案。在实际的应用场景中,也是浅复制更为常用。
2.JSON对象中的parse和stringify,JSON对象中的stringify可以把一个js对象序列化为一个JSON字符串,parse可以将JSON字符串反序列化为一个js对象,通过这两个方法,也可以实现对对象的深复制。
JavaScript的深拷贝与浅拷贝的更多相关文章
- javascript对象深拷贝,浅拷贝 ,支持数组
javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...
- 也来玩玩 javascript对象深拷贝,浅拷贝
经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...
- JavaScript的深拷贝和浅拷贝总结
深拷贝和浅拷贝 深拷贝:拷贝实例:浅拷贝:拷贝引用(原对象). 说深拷贝和浅拷贝之前,我先去了解了下高程书上的JavaScript的变量类型: 基本类型:undefined.null.Boolean. ...
- JavaScript的深拷贝和浅拷贝
一.数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型.. 1.基本数据类型的特点:直接存储在栈(stack ...
- 详解javascript的深拷贝与浅拷贝
1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...
- JavaScript 的 深拷贝和浅拷贝
深拷贝和浅拷贝都是针对的引用类型, JS中的变量类型分为值类型(基本类型)和引用类型: 对值类型进行复制操作会对值进行一份拷贝,而对引用类型赋值,则会对地址进行拷贝,最终两个变量指向同一份数据 一.先 ...
- JavaScript之深拷贝和浅拷贝
前言 工作中会经常遇到操作数组.对象的情况,你肯定会将原数组.对象进行‘备份’当真正对其操作时发现备份的也发生改变,此时你一脸懵逼,到时是为啥,不是已经备份了么,怎么备份的数组.对象也会发生变化.如果 ...
- javaScript深拷贝和浅拷贝简单梳理
在了解深拷贝和浅拷贝之前,我们先梳理一下: JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型 基本数据类型 数字Number 字符串 ...
- 读懂javascript深拷贝与浅拷贝
1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...
随机推荐
- perl6中的q/qq/qx/qqx
q不内插 qq内插 qx不内插 qqx内插
- fork与vfork区别
1. 地址空间各段拷贝: fork: 内核为子进程生成新的地址空间结构,拷贝父进程的代码段,数据空间,堆,栈到自身的地址空间,但注意:子进程的代码段并不会分配物理空间,而是指向父进程的代码段物理空间, ...
- Scrapy爬虫:抓取大量斗图网站最新表情图片
一:目标 第一次使用Scrapy框架遇到很多坑,坚持去搜索,修改代码就可以解决问题.这次爬取的是一个斗图网站的最新表情图片www.doutula.com/photo/list,练习使用Scrapy ...
- mysql utf8改utf8mb4
由于需要用到utf8mb4,之前是utf8现在给改成utf8mb4 查看当前环境 SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' ...
- [hadoop][基本原理]zookeeper场景使用
代码:https://github.com/xufeng79x/ZkClientTest 1. 简介 zookeeper的特性决定他适用到某些场景非常合适,比如典型的应用场景: 1.集群管理(Grou ...
- 2.ubuntu的使用
1. CTRL+ALT+T 可以将命令模式打开 2. 有可能没办法进行yum ,它会告诉你操作的方法 3. 有些操作需要获得root的权限才可以,我们得进入root状态 --> sudo pas ...
- JDBC原生数据库连接
我们在开发JavaWeb项目时,常会需要连接数据库.我们以MySQL数据库为例,IDE工具为eclipse,讲述数据库连接与基本操作. 第一步,我们在Web项目的WebContent中建一个简单的前端 ...
- JS对象转化为JSON字符串
js方法: JSON.stringify 把一个对象转换成json字符串 JSON.parse 把一个json字符串解析成对象. 实例: var jsObj = {}; jsObj.testArray ...
- [ Python ] 基本数据类型及属性(下篇)
1. 基本数据类型 (1) list 列表 (2) tuple 元组 (3) dict 字典 (4) set 集合 2. list 列表方法 Python 内置的一种数据类型, ...
- Python Flask装饰器登录验证
from flask import Flask,render_template,redirect,request,session app = Flask(__name__) app.secret_ke ...