vue对象深拷贝_JS 对象的深拷贝和浅拷贝
现象
我们先来看一个demo
// 我们先申明一个变量str1,
// 然后把变量str1负值(拷贝)给变量str2
// 最后对变量str2进行修改操作
var str1 = 'shen'
var str2 = str1
str2 += 'zhiyong'
console.log('str1:', str1) //shen
console.log('str2:', str2) //shenzhiyong
我们申明一个对象并对它进行相同的操作
var obj1 = {name: 'shen'
}
var obj2 = obj1
obj2.name = 'shenzhiyong'//期望输出
// obj1: {name: "shen"}
// obj2: {name: "shenzhiyong"}console.log('obj1:', obj1) // obj1: {name: "shenzhiyong"}
console.log('obj2:', obj2) // obj2: {name: "shenzhiyong"}
我们不难发现结果并不是我们预期的那样, 这是为什么呢?如果将obj1改成数组对象进行操作,亦是同样的结果。
原因:由于String类型属于基本数据类型,Object(Array)属于引用数据类型。当我们申明一个基本类型并对它进行赋值的时候,计算机会将值保存在栈内存中。而当我们申明一个引用数据类型并对它进行赋值的时候,计算机会将值保存在堆内存中,引用类型变量其实就是一个指针指向堆内存中。如果复制两相同的引用类型变量,其实它们最终指向同一个对象或者说堆内存空间。
关于JavaScript的数据类型 我们先埋下一个坑!
一、浅拷贝
对象和数组的浅拷贝代码如下:
var obj1 = {name: 'shen'
}
var obj2 = obj1
obj2.name = 'shenzhiyong'console.log('obj1:', obj1) // obj1: {name: "shenzhiyong"}
console.log('obj2:', obj2) // obj2: {name: "shenzhiyong"}var arr1 = [1,2,3]
var arr2 = arr1
arr2.push(4)
console.log('arr1:', arr1) // arr1: [1,2,3,4]
console.log('arr2:', arr2) // arr2: [1,2,3,4]
浅拷贝的意思就是只复制引用,没有复制真正的值。有时候我们只是想保留对象的数据,单纯想改变obj2和arr2的值,但是原对象的数据也发生了改变。很多时候这种情况都不是我们想要的。为了解决这个问题: 深拷贝它来了!
二、深拷贝
JSON方法
var obj1 = {name: 'shen'
}
var obj2 = JSON.parse(JSON.stringify(obj1))
obj2.name = 'shenzhiyong'console.log('obj1:', obj1) // obj1: {name: "shen"}
console.log('obj2:', obj2) // obj2: {name: "shenzhiyong"}
优点:简单明了,方便记忆
缺点:看下面代码。当对象里面出现函数的时候就不适用了。
var obj1 = {name: 'shen',show: function (argument) {console.log(1)}
}
var obj2 = JSON.parse(JSON.stringify(obj1))
console.log('obj1:', obj1) // obj1: {name: "shen", show: ƒ}
console.log('obj2:', obj2) // obj2: {name: "shen"}
手写递归方法
function deepCopy(obj) {var newobj = obj.constructor === Array ? [] : {};if (typeof obj !== 'object') {return obj;} else {for (var i in obj) {if (typeof obj[i] === 'object'){ //判断对象的这条属性是否为对象newobj[i] = deepCopy(obj[i]); //若是对象进行嵌套调用}else{newobj[i] = obj[i];}}}return newobj; //返回深度克隆后的对象
}var obj1 = {name: 'shen',show: function (argument) {console.log(1)}
}
var obj2 = deepCopy(obj1)
console.log('obj1:', obj1) // obj1: {name: "shen", show: ƒ}
console.log('obj2:', obj2) // obj2: {name: "shen"}
优点:能够实现对象和数组的深拷贝
缺点:如果拷贝的对象嵌套过深的话,会对性能有一定的消耗
第三方库 jQuery.extend 和 lodash
$.extend( true, object1, object2 ); // 深度拷贝
$.extend( object1, object2 ); // 浅拷贝var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]); // => false
大佬写的东西,我只能说:逃
三、重点来了:具有局限性的深拷贝(有些面试官就喜欢问这个地方的东西)
当对象或者数组内部的都是基本数据类型的话,以下的方式可以实现深拷贝。但是如果出现了引用类型嵌套引用类型的话。以下方法将不可用。
看下面代码:
var obj = {name: 'shen'
}var obj2 = {innner: {name: 'shen'}
}
以下方法仅支持obj此类对象的深度拷贝不支持obj2此类对象
es6解析结构 「...」
var obj1 = {name: 'shen',show: function (argument) {console.log(1)}
}
var obj2 = { ...obj1 }
obj2.name = 'shenzhiyong'
console.log('obj1:', obj1) // obj {name: "szy", show: ƒ}
console.log('obj2:', obj2) // obj2 {name: "shenzhiyong", show: ƒ}
Object.assign()
var obj1 = {name: 'shen',show: function (argument) {console.log(1)}
}
var obj2 = Object.assign(obj1)
obj2.name = 'shenzhiyong'
console.log('obj1:', obj1) // obj {name: "szy", show: ƒ}
console.log('obj2:', obj2) // obj2 {name: "shenzhiyong", show: ƒ}
数组中的slice() & concat()
var arr1 = [1,2,3]
var arr2 = arr1.slice() // 方法一
// var arr2 = arr1.concat() //方法二
arr2.push(4)
console.log('arr1:', arr1) // arr1: [1, 2, 3]
console.log('arr2:', arr2) // arr1: [1, 2, 3, 4]
总结:要想实现真正意义的深拷贝,个人觉得还是递归的方法比较靠谱。其实看第三方的库也是采用这样的做法。在实际的生产当中,我使用的是lodash。
放水完毕!
vue对象深拷贝_JS 对象的深拷贝和浅拷贝相关推荐
- python怎样给对象赋值_Python对象赋值、浅拷贝和深拷贝
总结: 1.copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象 2.copy.deepcopy 深拷贝 拷贝对象及其子对象 1.对象赋值 will = ["Will&quo ...
- python中一切数据都是对象吗_python中的深拷贝(deepcopy)和浅拷贝(copy)
前言 在很多语言中都存在深浅拷贝两种拷贝数据的方式,Python中也不例外.本文中详细介绍了Python中的深浅拷贝的相关知识,文章的内容包含: 对象.数据类型.引用 赋值 浅拷贝 深拷贝 一.Pyt ...
- js 对象深拷贝、对象数组深拷贝的几种方法总结
写前端的时候经常会遇到对象的拷贝,一般我们会用到深拷贝,深拷贝就是完完整整的将一个对象从内存中拷贝一份出来,放到另一块新开辟的内存中去.向下面这种赋值是浅拷贝,a.b都是对同一块内存进行引用,a.b哪 ...
- vue 对象继承_JS面向对象—对象的继承
面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过"类&qu ...
- vue 深度拷贝数组_前端深拷贝和浅拷贝
在前端攻城狮的工作实际应用中,有很多情况下在处理数据的时候,会用到数据的深拷贝和浅拷贝 例如:vue中数据是双向绑定的,页面显示依赖于从后台获取到的数据,但要将这个数据当做参数发送给另外一个接口的时候 ...
- js 浅拷贝直接赋值_JS中的赋值、浅拷贝与深拷贝
作者:奚杰 拷贝是写代码中经常使用的方法.浅拷贝与深拷贝是指拷贝的两种情况.本文将深入探究JS的赋值.浅拷贝与深拷贝. 数据类型 在探究深拷贝与浅拷贝之前,我们先梳理一下JS的数据类型.在JavaSc ...
- ES6 深拷贝_JS基本数据类型和引用数据类型的区别及深浅拷贝
1.栈(stack)和堆(heap) stack为自动分配的内存空间,它由系统自动释放:而heap则是动态分配的内存,大小也不一定会自动释放 2.数据类型 JS分两种数据类型: 基本数据类型:Numb ...
- vue更新数组和对象
vue更新数组和对象 https://cn.vuejs.org/v2/guide/list.html#数组更新检测 更改数组对象 let items=this.formValidate.items; ...
- vue中的props对象
vue中的props对象 1.props对象的定义 props其实是properties的缩写,props对象是用来定义属性的.props对象可以接受数组形式的参数又或者是对象形式的参数. 数组形式 ...
最新文章
- Firefox 插件:鲜味 del.icio.us,和朋友分享你的收藏
- 第五周课程总结试验报告(三)
- python安装第三方库
- 使用ffmpeg合并视频文件的三种方法
- 将社交登录添加到Spring MVC Web应用程序:配置
- luogu P1427 小鱼的数字游戏
- 【Python3网络爬虫开发实战】 1.7.1-Charles的安装
- python在什么平台开发_python主要用于开发什么
- java sql 写入万条数据_如何快速向数据库插1000万数据?4种方法对比,它简单却速度最快
- 关于学习新知识的一点想法
- 浏览器宽度和高度的说明
- win下编译TNN安卓库(静态或者动态) + android studio ndk调用
- win10用win7的图片查看器
- 人生无常,心安便是归处
- BT-3の蓝牙技术原理のBT协议の蓝牙核心协议の链路管理协议(LMP)
- 数学到底有多重要呢?
- iOS事件传递链与响应链
- 关于unityHDRP RenderTexture透明通道搜集资料
- 笔记本插网线无法联网解决方法
- java as关键字_Java 关键字专题
热门文章
- pytorch中调整学习率: torch.optim.lr_scheduler
- 51nod1380 夹克老爷的逢三抽一
- Eclipse 使用 SVN 插件后修改用户方法汇总
- JSON C# Class Generator ---由json字符串生成C#实体类的工具(转)
- Wayland 1.0 发布,图形服务器
- FLEX教程:改变LIST控件项被选中的背景提示效果.
- 22款Android App传藏后门用广告耗手机电量
- 顺藤摸瓜的解决GDB的DEBUG中出现的小问题
- 读《世界是数字的》笔记
- 比特币网站Flexcoin遭黑客攻击 损失极大 被迫关闭