JavaScript对象的浅拷贝与深拷贝实例分析
作者:筱葭 发布时间:2024-04-16 09:46:34
本文实例讲述了JavaScript对象的浅拷贝和深拷贝。分享给大家供大家参考,具体如下:
1、浅拷贝
仅仅复制对象的引用,而不是对象本身。
var person = {
name: 'Alice',
friends: ['Bruce', 'Cindy']
}
var student = {
id: 30
}
student = simpleClone(person, student);
student.friends.push('David');
alert(person.friends);
function simpleClone(oldObj, newObj) {
var newObj = newObj || {};
for (var i in oldObj)
newObj[i] = oldObj[i];
return newObj;
}
使用在线HTML/CSS/JavaScript代码运行工具:http://tools.aspxhome.com/code/HtmlJsRun,测试运行结果:
给子对象的数组类型的属性添加一个新值,父对象的该属性值也被篡改。
2、深拷贝
把复制的对象所引用的全部对象都复制一遍,能够实现真正意义上的数组和对象的拷贝。
浅拷贝的问题:如果父对象的属性值为一个数组或另一个对象,那么实际上子对象获得的只是一个内存地址,而不是对父对象的真正拷贝,因此存在父对象被篡改的可能。
解决方法:使用深拷贝。
var person = {
name: 'Alice',
friends: ['Bruce', 'Cindy']
}
var student = {
id: 30
}
student = deepClone(person, student);
student.friends.push('David');
alert(person.friends); // 'Bruce', 'Cindy'
function deepClone(oldObj, newObj) {
var newObj = newObj || {};
newObj = JSON.parse(JSON.stringify(oldObj));
return newObj;
}
使用在线HTML/CSS/JavaScript代码运行工具:http://tools.aspxhome.com/code/HtmlJsRun,测试运行结果:
3、实现深拷贝的方法
1) 方法1:使用JSON.parse()方法
function deepClone(oldObj, newObj) {
var newObj = newObj || {};
newObj = JSON.parse(JSON.stringify(oldObj));
return newObj;
}
优点:
简单易用。
缺点:
①会抛弃对象的constructor,即,深拷贝后,不管该对象原来的构造函数是什么,在深拷贝之后都会变成Object。
②能正确处理的对象只有 Number, String, Boolean, Array,即那些能够被JSON直接表示的数据结构,RegExp对象等无法通过这种方式深拷贝。
2) 方法2:递归拷贝
function deepClone(oldObj, newObj) {
var newObj = newObj || {};
for (var i in oldObj) {
if (typeof oldObj[i] === 'object') {
newObj[i] = (oldObj[i].constructor === Array) ? [] : {};
arguments.callee(oldObj[i], newObj[i]);
}
else
newObj[i] = oldObj[i];
}
return newObj;
}
问题:当遇到两个互相引用的对象,会出现死循环的情况。
解决方法:在遍历时判断两个对象是否相互引用(如oldObj.property === newObj),如果是则退出循环。
function deepClone(oldObj, newObj) {
var newObj = newObj || {};
for (var i in oldObj) {
var prop = oldObj[i];
if (prop === newObj)
continue;
if (typeof prop === 'object') {
newObj[i] = (prop.constructor === Array) ? [] : {};
arguments.callee(prop, newObj[i]);
}
else
newObj[i] = prop;
}
return newObj;
}
3) 方法3:使用Object.create()
方法
function deepClone(oldObj, newObj) {
var newObj = newObj || {};
for (var i in oldObj) {
var prop = oldObj[i];
if (prop === newObj)
continue;
if (typeof prop === 'object')
newObj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
else
newObj[i] = prop;
}
return newObj;
}
4)方法4:使用jQuery.extend()
和jQuery.fn.extend()
请见:https://www.aspxhome.com/article/144424.htm
希望本文所述对大家JavaScript程序设计有所帮助。
来源:https://blog.csdn.net/zhouziyu2011/article/details/70477126
猜你喜欢
- MySQL BETWEEN 用法MySQL BETWEEN 语法BETWEEN 运算符用于 WHERE 表达式中,选取介于两个值之间的数据范
- 要想从命令行启动mysqld服务器,你应当启动控制台窗口(或“DOS window”)并输入命令:C
- 首先要下载:Graphviz - Graph Visualization Software安装完成后将安装目录的bin 路径加到系统路径中,
- 以前的Sony Ericsson牌DVD影碟机坏掉了,上周到沃尔玛买了个philips的回来,于是又淘了一些DVD回来看。在使用遥控的时候忽
- 本文实例分析了python开发之str.format()用法。分享给大家供大家参考,具体如下:格式化一个字符串的输出结果,我们在很多地方都可
- 1. OpenCV:模板匹配。 获得小跳棋中心位置2.
- 前言说起面试,很多同学都经历过,但是 面试中 可能会遇到各种问题,MySQL 的问题 也是非常多,最近我也经常面试,也希望问一些数据库一些偏
- 安装 SQL2000 时,系统经常会提示:操作被挂起,要求重新启动计算机,如图1: 图1重新启动后,再次安装时问题仍然存在。解决办
- 0.object类源码class object: """ The most base type &
- 阅读《YUI学习笔记(1)》YAHOO.lang.dump 与 YAHOO.lang.substitute。1.&nbs
- vue组件在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是有中间介质,子向父的介质是自定义事件,父向子的介质
- 两周前,在给颜值在线的 flame 提交了几个 PR 之后,我将它封装成了容器,用于书签和在线应用的管理。但是在迁移个人
- 什么是运行时配置(Runtime Configuration,rc)Matplotlib使用matplotlibrc配置文件来自定义图形的各
- 我就废话不多说了,还是直接看代码吧!a = [1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1]b = ['
- 项目场景:Python版本:3.8因公司业务需求,须开发一套局域网内视频会议软件,此次采用Python实现此功能。程序编写完并在编译器实现此
- 如下:数据文件:上海机场 (sh600009)24.113.58东风汽车 (sh600006)74.251.74中国国贸 (sh600007
- 最近在工作中遇到了一个小问题,如果要将字符串型的数据转换成dict类型,我第一时间就想到了使用json函数。但是里面出现了一些问题1、通过j
- 1. do:1)形式:do 'filename';说明:这里filename需要添加单引号,否则会出错;filename可以
- 一、把一个字符串的内容提取出来,并放到字典中流程如下: 1、得到字符串s,通过分割提取得到s1(是个列表) s=”name=lyy&
- 刚开始学习tensorflow,还不太会用,开个博记录,今天遇到一个问题是用tf.layers.dense创建的全连接层,如何查看权重?知道