JavaScript中的对象引用和复制
在JavaScript分为两种原始值和引用值类型,原始值之间的复制是值对值得复制,而引用类型则是引用对引用的复制;
// 原始值的复制;
let num1 = 1;
let num2 = num1;
num2++;
console.log(num1,num2); // 1,2
// 引用类型的复制;
let joe = {
name:"joe",
age:20
}
let john = joe;
john.name = 'john';
console.log(john === joe,joe.name); // true john
如你所见,当我们把joe 赋值给john时实际上并没有完全复制一个新的,就好像是下面这样:

图片来自 “现代JavaScript教程” 网站;
Object.assign(target,arg1,arg2,...)方法用于将第二个参数及以后所有的对象都合并到第一个对象中,并返回第一个对象;
let user = {
name:"申屠肆",
hobbies:{
first:'JavaScript',
second:'Node'
}
}
let user_copy = Object.assign({job:'Web开发'},user,);
user_copy.name = '谢必安';
user_copy.hobbies['third'] = 'Python';
console.log(user_copy.name,user.name);
console.log(user_copy.hobbies,user.hobbies);
//控制台
谢必安 申屠肆
{ first: 'JavaScript', second: 'Node', third: 'Python' } { first: 'JavaScript', second: 'Node', third: 'Python' }
虽然Object.assign可以达到我们想要的效果,但是,可以发现,如果合并的对象的某个键对应的值仍然是对象,则还是会存下对象的引用;
接下来,让我们探寻更进一步的方案
// 采用递归 + JSON对象的方法 来完成深度复制
function deep_clone(source,target = {}) {
for(let key in source) {
if(source[key].constructor === Object) {
target[key] = deep_clone(source[key])
}else if (source[key].constructor === Array) {
target[key] = JSON.parse(JSON.stringify(source[key]))
} else {
target[key] = source[key];
}
}
return target;
}
让我们来试一下
var ball = {
name:'足球',
shape:{
text:'圆形',
size:40
},
abc:[1],
def:[{user:'谢绝'}]
}
function deep_clone(source,target = {}) {
for(let key in source) {
if(source[key].constructor === Object) {
target[key] = deep_clone(source[key])
}else if (source[key].constructor === Array) {
target[key] = JSON.parse(JSON.stringify(source[key]))
} else {
target[key] = source[key];
}
}
return target;
}
var ball_copy = deep_clone(ball);
ball_copy.shape.text="方形";
ball_copy.abc.push(2);
ball_copy.def[0].user = "谢绝-copy";
console.log(ball_copy,ball);
// 控制台打印
{
name: '足球',
shape: { text: '方形', size: 40 },
abc: [ 1, 2 ],
def: [ { user: '谢绝-copy' } ]
} {
name: '足球',
shape: { text: '圆形', size: 40 },
abc: [ 1 ],
def: [ { user: '谢绝' } ]
}
使用该方法需要注意的是,不能有“环形结构”
JavaScript中的对象引用和复制的更多相关文章
- JavaScript 中的对象引用
ECMAScirpt 变量有两种不同的数据类型:基本类型,引用类型.也有其他的叫法,比如原始类型和对象类型,拥有方法的类型和不能拥有方法的类型,还可以分为可变类型和不可变类型,其实这些叫法都是依据这两 ...
- JavaScript 中的对象深度复制(Object Deep Clone)
JavaScript中并没有直接提供对象复制(Object Clone)的方法. JavaScript中的赋值,其实并不是复制对象,而是类似`c/c++`中的引用(或指针),因此下面的代码中改变对象b ...
- javascript中的对象,原型,原型链和面向对象
一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...
- javascript中关于深复制与浅复制的问题
在javascript中,变量的类型分为基本类型和引用类型. 对于基本类型的变量来说,值的复制以及作为函数参数实参传递的过程都是值的复制传递,换句话说,是会在内存中开辟出一个新空间用于存放新的值的.这 ...
- 【转】JavaScript中的对象复制(Object Clone)
JavaScript中并没有直接提供对象复制(Object Clone)的方法.因此下面的代码中改变对象b的时候,也就改变了对象a. a = {k1:1, k2:2, k3:3}; b = a; b. ...
- Javascript中的一种深复制实现
在javascript中,所有的object变量之间的赋值都是传地址的,可能有同学会问哪些是object对象.举例子来说明可能会比较好: typeof(true) //"boolean&qu ...
- 深度解析javascript中的浅复制和深复制
原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...
- 对 JavaScript 中的5种主要的数据类型进行值复制
定义一个函数 clone(),可以对 JavaScript 中的5种主要的数据类型(包括 Number.String.Object.Array.Boolean)进行值复制 使用 typeof 判断值得 ...
- javascript 中的深复制 和 其实现方法
首先,我们需要明白什么是深复制(侧重指对象方面)? 在javascript中,复制分为浅复制和深复制,个人理解,浅复制就是直接将引用复制,复制前后的两个对象指向同一个内存地址,对其中一个进行操作,另外 ...
随机推荐
- javascript判断浏览器访问,刷新,返回
话不多说,直接上 if (window.performance.navigation.type === 0/* 正常访问 */) { // 你要干的事 } else if (window.perfor ...
- ubuntu更新下载软件卡住0% [Connecting to archive.ubuntu.com (2001:67c:1360:8001::23)]
一台ubuntu系统,查看硬件和配置环境的时候发现下载卡住了 根据提示就是有ipv6地址,系统也是配置了ipv6地址的.海外机器,而且可以ping通域名 最佳解决方案 我想出了如何让apt-get再次 ...
- pycharm安装完成后的一些基本设置
1.设置背景色 file-->Setting-->Appearance&Behavior-->Appearance 2.设置主题 settings --> editor ...
- 使用amoeba实现mysql读写分离
使用amoeba实现mysql读写分离 1.什么是amoeba? Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发.座落与Client.DB Server(s)之间.对客户端透明. ...
- 广告召回 Query-Ad Matching
小结: 1.最为基础的召回链路就是要保证召回层的相关性,但是相关性高的广告并不一定具有很高的商业价值,所以开始尝试将一些商业化业务指标作为召回的依据 百度凤巢新一代广告召回系统--"莫比乌斯 ...
- 对话 CTO〡用声音在一起,听荔枝 CTO 丁宁聊 UGC 声音互动平台的技术世界 原创 王颖奇 极客公园 2018-12-01
https://mp.weixin.qq.com/s/jfHFXZpzbAEbHKkCMSev6w 对话 CTO〡用声音在一起,听荔枝 CTO 丁宁聊 UGC 声音互动平台的技术世界 原创 王颖奇 极 ...
- scala/java等其他语言从CSV文件中读取数据,使用逗号','分割可能会出现的问题
众所周知,csv文件默认以逗号","分割数据,那么在scala命令行里查询的数据: 可以看见,字段里就包含了逗号",",那接下来切割的时候,这本应该作为一个整体 ...
- jasper使用table组件设计复杂的表头
1.1 设计报表模板 1.1.1 新建模板DemoReport5.jrxml,去掉不需要的Band,保留Title,Page Header,Detail 1 , PageFooter.将组件Table ...
- P6584 重拳出击
写在前面 来给 zrm 大佬的题写一篇题解. 这题代码实现难度不高,但是比较锻炼思维,而且应该有不少种解法.着实是一道质量很高的题目. 算法思路 首先呢,显然当小 Z 向当前节点的一棵子树走去时,这棵 ...
- 使用 shell 脚本自动对比两个安装目录并生成差异补丁包
问题的提出 公司各个业务线的安装包小则几十兆.大则几百兆,使用自建的升级系统向全国百万级用户下发新版本时,流量耗费相当惊人.有时新版本仅仅改了几个 dll ,总变更量不过几十 K 而已,也要发布一个完 ...