《JavaScript总结》深拷贝和浅拷贝
在javascript中,数据主要分基本类型和引用类型两种。
基本类型的赋值比较简单,但是引用类型的赋值,会存在一些问题,那我们用代码来分析一下。
一、浅拷贝
var one = "测试1";
var two = one;
two = "测试2";
console.log(one);
上面代码中,声明了一个变量one ,值为:“测试1” ,然后将变量one 赋值给了变量two ,
之后我们把变量two的值修改成:“测试2” 了,这时我们从控制台打印变量one ,输出的结果是:“测试1”。
也就是说修改变量two的值并不会对变量one造成影响。
那我们再来看下面这个例子:
var arr = ['白色','蓝色','紫色'];
var temp = arr;
temp[1]="天蓝色";
console.log(arr);
上面这段代码,控制台打印输出了 ‘白色’,'天蓝色','紫色' ,这是怎么回事呢?我们明明修改的是temp,怎么arr也被修改了?
这其实很简单,因为在javascript中,数组属于引用类型数据。在上面的例子中,当把arr赋值给temp时,其实只是把访问地址赋值给了temp
我们来分析一下代码
var arr = ['白色','蓝色','紫色'];
在javascript中,数组的大小是不确定的,这时js会在堆内存中建立一块内存,用来存一个数组,而这个数组的值目前为:['白色','蓝色','紫色'] ,然后会生成一个地址,并且赋值给了arr ,
所以说arr存的是 ['白色','蓝色','紫色'] 在堆内存中的访问地址。
var temp = arr;
因为arr存的是一个地址,这时将arr赋值给了temp ,所以temp也拥有访问['白色','蓝色','紫色']的地址了。
temp[1]="天蓝色";
那么这时我们将temp[1]的值修改成了“天蓝色”,这一操作,首先temp通过地址访问堆内存对应的数据,并且修改了数据。
因为arr和temp存的只是访问同一个源的地址,源被temp改变了,arr再次访问时,访问的也就是改变过的源了。
但有时候,我们修改一个数据的时候,并不想影响另一个数据,使用深拷贝就可以解决这个问题。
二、深拷贝
数组中的深拷贝
数组实现深拷贝的方法:使用slice()或cancat()方法,或者是使用循环将当前数组的值,一个一个添加到新的数组中即可。
var arr = [1,3,4];
var temp = arr.slice(0);
temp[0]=6;
console.log(arr);//输出 1,3,4 不会被temp影响
var arr = [1,3,4];
var temp =arr.concat([]);
temp[0]=6;
console.log(arr);//输出1,3,4 不会被temp影响
其实上面两种都属于简单的深拷贝,如果是二维数组、三维数组呢?我们看一个例子
var ac = [1,[2,3],4];
var ad = ac.slice(0);
ad[1][0]=6;
ad[0]=5;
console.log(ac);
控制台输出结果如下:

使用了简单的深拷贝(slice方法)之后,可以发现ac的第一个值确实不受ad的影响,但是ac的第二个值却随着ad的改变而改变了。更深层的拷贝怎么办呢?其实可以利用递归函数来解决这个问题
var duowei = [1,[2,3],4];
function dispose(data){
var out = [];
for(var i =0;i<data.length;i++){
if(data[i] instanceof Array){
out[i]=dispose(data[i]);
}else{
out[i]=data[i];
}
}
return out;
} var result = dispose(duowei);
result[1][0]=9;
console.log(duowei);
对象中的深拷贝
在对象中简单的深拷贝可以使用Object.assign来实现
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) //
复杂的深拷贝可以使用JSON.parse(JSON.stringify(object))来解决,不过这个方法有一些局限性。
- 会忽略
undefined - 会忽略
symbol - 不能序列化函数
- 不能解决循环引用的对象
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
其实方法有很多,需要自己去挖掘。
这里在分享一个数组和对象实现简单深拷贝通用的方法:通过展开运算符(…)来实现。
let a = {
age: 1
}
let b = {...a}
a.age = 2
console.log(b.age) //
《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的深拷贝与浅拷贝
深拷贝和浅拷贝是在面试中经常遇到的问题.今天在这里总结一下. 深拷贝与浅拷贝的问题,涉及到JavaScript的变量类型,先来说说变量的类型,变量类型包括基本类型和引用类型. 基本类型:Undefin ...
- 详解javascript的深拷贝与浅拷贝
1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...
- JavaScript 的 深拷贝和浅拷贝
深拷贝和浅拷贝都是针对的引用类型, JS中的变量类型分为值类型(基本类型)和引用类型: 对值类型进行复制操作会对值进行一份拷贝,而对引用类型赋值,则会对地址进行拷贝,最终两个变量指向同一份数据 一.先 ...
- JavaScript之深拷贝和浅拷贝
前言 工作中会经常遇到操作数组.对象的情况,你肯定会将原数组.对象进行‘备份’当真正对其操作时发现备份的也发生改变,此时你一脸懵逼,到时是为啥,不是已经备份了么,怎么备份的数组.对象也会发生变化.如果 ...
- javaScript深拷贝和浅拷贝简单梳理
在了解深拷贝和浅拷贝之前,我们先梳理一下: JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型 基本数据类型 数字Number 字符串 ...
- 读懂javascript深拷贝与浅拷贝
1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...
随机推荐
- opencv的安装
网上搜了好多文章安装opencv3.2.0都未能成功,写的也个不相同,后来找到了opencv官网的教程,看了后才发现,这上面才是最详细的. 于是按照opencv官网教程安装,安装的一半就中断了.经过苦 ...
- 【竞价网站绝技】根据访客ip,页面显示访客所属城市的html代码(借用YY IP地址库)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 偏差(Bias)和方差(Variance)——机器学习中的模型选择zz
模型性能的度量 在监督学习中,已知样本 ,要求拟合出一个模型(函数),其预测值与样本实际值的误差最小. 考虑到样本数据其实是采样,并不是真实值本身,假设真实模型(函数)是,则采样值,其中代表噪音,其均 ...
- Exp3 免杀原理与实践_05齐帅
Exp3 免杀原理与实践 20154305_齐帅 想要弄懂免杀,一定得先把基础问题弄明白啊~~ 一.基础问题回答 (1)杀软是如何检测出恶意代码的? - -检测特征码: 依靠分析总结出计算机病毒中常出 ...
- 哈夫曼(Huffman)树和哈夫曼编码
一.哈夫曼(Huffman)树和哈夫曼编码 1.哈夫曼树(Huffman)又称最优二叉树,是一类带权路径长度最短的树, 常用于信息检测. 定义: 结点间的路径长度:树中一个结点到另一个结点之间分支数目 ...
- 在windows下golang安装zmq3小记
备忘这个 安装 TDM-GCChttp://tdm-gcc.tdragon.net/download 设置环境变量set C_INCLUDE_PATH=d:\DevTools\Zmq\ZeroMQ 3 ...
- H3C 路由策略(人为打环)
拓扑如上 任务1:去除环路双ospf 引入 造成路由环路一边是 1 一边是10关掉任意lo口都会生成新的路由表 但是路由表指向不对 变成了一个圆 我们可以采用引入路由打上tag ...
- 支持Linux,嗅探和注入功能的网卡
支持的WiFi USB 以下是已知可以很好地支持Linux,嗅探和注入功能,外部天线(可以替换)和强大的TX功率以及良好的RX灵敏度的Wifi卡的列表 TP-LINK TL-WN722N(仅限卷1) ...
- UDF函数 解码url
背景 URL 的编码 是ASCII十六进制格式.数仓接受到前端上报的URL,要对URL字段解码. 如要将 https"Fmybook.do%3Frequest_type%3D%26type% ...
- 在码云(gitee)上展开程序类课程教学
码云主要提供了源代码管理(Git/SVN)功能,最近又推出了高校版让普通老师也能利用起来以供教学使用. 学生与老师不仅能利用其管理代码,更重要的是我们的程序教学能通过对git的使用来引入业界流行的软件 ...