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


猜你喜欢
- 这篇文章主要介绍了如何基于Python实现自动扫雷,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可
- 本文实例讲述了C#操作SQLite数据库帮助类。分享给大家供大家参考,具体如下:最近有WPF做客户端,需要离线操作存储数据,在项目中考虑使用
- 从 Google 的一个细节说起:整个虚线框都是“Next”的可点击区域。看似不经意,却直接提升了细节的可用性。其它页码也巧妙地和上面的字母
- 概述nodejs内置模块指的是除默认提供的语法之外,提供的美容,无需下载,直接引入,引入只写名称即可。nodejs内置模块:1、path模块
- 一、前期准备CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT,
- 0.偶然间看到一个奇怪的现象>>> x = 1>>> a = var()>>> a[&
- Python中,队列是线程间最常用的交换数据的形式。Queue模块是提供队列操作的模块,虽然简单易用,但是不小心的话,还是会出现一些意外。创
- 目录1. 最直观的相加2. 借助 itertools3. 使用 * 解包4. 使用 extend5. 使用列表推导式6. 使用 heapq7
- 前言前面我们介绍了 pandas 的基础语法操作,下面我们开始介绍 pandas 的数据读写操作。pandas 的 IO API 是一组顶层
- 话不多说,请看代码:function removeRepeat(data) {var temp = "";var mai
- 当我们在终端上(比如Goland)运行gin框架搭建的服务时,会发现输出的日志是可以带颜色的。比如下图中的最后一行,就是请求一个方法时的输出
- 这个操作在numpy数组上的操作感觉有点麻烦,但是也没办法。例如 a = [[1,2,3], [4,5,6], [7,8,9]]取 a 的
- 1 基本概念1.1 命名空间 (namespace)命名空间是变量名到对象的映射(name -> obj)。目前大多数的命名空间以类似
- 进程与线程的历史我们都知道计算机是由硬件和软件组成的。硬件中的CPU是计算机的核心,它承担计算机的所有任务。 操作系统是运行在硬件之上的软件
- 一 MySQL WorkbenchMySQL Workbench提供DBAs和developers一个集成工具环境:1)数据库设计和建模2)
- 定义神经网络继承nn.Module类;初始化函数__init__:网络层设计;forward函数:模型运行逻辑。class NeuralNe
- 1、from ... import 导入from package import module1, module2, module3, ...
- 我使用的是anaconda。我推荐大家使用anaconda,对环境依赖关系处理的比较好。不用浪费太多时间在安装模块上。首先安装pyinsta
- 一个网站的一个页面download.asp通过判断referer来确定是不是从他本站点过来的链接,使用这个功能我们可以用来防止下载盗链,当然
- 在Django中有非常强大的URL模块,可以按照开发者的想法来制定清晰的URL,同时支持正则表达式。此外,在URL中还可以传递参数。1.&n