前言

经常会在一些网站或博客看到“深克隆”,“浅克隆”这两个名词,其实这个很好理解,今天我们就在这里分析一下js深拷贝和浅拷贝

浅拷贝

我们先以一个例子来说明js浅拷贝:

var n = {a: 1, b: 2}
var m = n
m.a = 12
console.log(n.a) // ?

上面显然 n.a 的值会变为 12,这就是js浅拷贝。浅拷贝只是拷贝的指向对象的指针,本质上还是指向同一个对象。

深拷贝

同样我们还是以一个例子来说明啥叫 js deep clone

var n = {a: 1, b: 2}
var m = {a: n.a, b: n.b}
m.a = 12
console.log(n.a) // ?

上面的输出结果显然还是 1 ,m 和 n 虽然所有的属性和值全部相同,但是它们是两个不同的对象,它们在堆内存中占据两块不同的内存地址,这就是深度拷贝。深度拷贝就是完全复制一个新的对象出来,它们在堆内存中完全占据两个不同的内存地址。

js 实现深拷贝

简单一维数据结构

  1. 手动直接赋值

上面的 深拷贝 例子

  1. 利用 ES6 Object.assign() 方法

const obj = {name: 'cc', age: 24}
const newObj = Object.assign({}, obj)
obj.name = 'cc1'
newObj.name ? // cc

二维的数据结构及以上

  1. 简单粗暴的方式:JSON.parse(JSON.stringify(obj))

缺点:它会对对于正则表达式类型、函数类型等无法进行深拷贝,而且会直接丢失相应的值,还有就是它会抛弃对象的 constructor

var obj = { a: {a: "cc"}, b: 123 }
var newObj = JSON.parse(JSON.stringify(obj))
newObj.b = 1234
console.log(obj) // {a: {a: 'cc'}, b: 123}
console.log(newObj); // {a: {a: 'cc'}, b: 1234}
  1. 利用 jQuery

// 浅拷贝
var newObj = $.extend({}, obj) // 深拷贝
var newObj = $.extend(true, {}, obj) // 要求第一个参数必须为true
  1. 自己动手实现一个简单深拷贝函数
function deepClone(obj){
if(typeof obj !== "object" || obj === null) return
let newObj = obj instanceof Array ? [] : {}
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key] = typeof obj[key] === "object" && obj[key] !== null ? deepClone(obj[key]) : obj[key]
}
}
return newObj
}
let obj = {a: 1, b: function(){}, c: {d: 2}}
deepClone(obj) // {a: 1, b: function(){}, c: {d: 2}}

对于深拷贝来说最常用的就是这些方法,当然还有其他的一些库,比如 deepCopylodash等,这里就不深究。

老生常谈之js深拷贝与浅拷贝的更多相关文章

  1. js 深拷贝和浅拷贝

    js 深拷贝和浅拷贝 先举一下项目中遇到的两个例子: 例子1: var json = $.parseJSON(data.data);//data.data是接口返回的值var a = json.cha ...

  2. 关于JS深拷贝和浅拷贝

    最近在前端开发中遇到一些问题,就是数组中的某个对象或某个对象的值改变之后,在不刷新页面的时候需要重新渲染值时,页面显示的还是原来的数据.比如: data{ A:[{id:1,num:1},{id:2, ...

  3. 在vue中子组件修改props引发的对js深拷贝和浅拷贝的思考

    不管是react还是vue,父级组件与子组件的通信都是通过props来实现的,在vue中父组件的props遵循的是单向数据流,用官方的话说就是,父级的props的更新会向下流动到子组件中,反之则不行. ...

  4. JS 深拷贝和浅拷贝概念,以及实现深拷贝的三种方式

    一.理解堆栈,基本数据类型与引用数据类型 1.堆栈 栈(stack):系统自动分配的内存空间,内存会由系统自动释放,用来存放函数的参数值,局部变量的值等,特点是先进后出. 堆(heap):系统动态分配 ...

  5. 面试遇到的坑JS深拷贝和浅拷贝

    首先要搞明白深拷贝和钱拷贝的区别要先搞明白 栈和堆的区别 一.栈 栈存储基础数据类型,如: String.Number.Boolean.Null.Underined,这些简单的基础数据类型能够直接存储 ...

  6. js深拷贝与浅拷贝

    1 基础知识:基本类型与引用类型 JS中可以把变量分成两部分,基本类型和引用类型. 基本类型包括:Undefined.Null.Boolean.Number和String: 引用类型值可能由多个值构成 ...

  7. js深拷贝、浅拷贝

    浅拷贝: 只针对当前对象的属性进行拷贝,若当前对象的属性是引用类型时,这个不考虑,不进行拷贝.若属性是引用类型,拷贝后引用的是地址,如果进行更改,会影响拷贝的原对象属性. 深拷贝:针对当前对象的数据的 ...

  8. js 深拷贝和浅拷贝理解

    作者:进击的袋鼠链接:https://www.zhihu.com/question/23031215/answer/124017500来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  9. [转] js深拷贝和浅拷贝

    一.数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致 ...

随机推荐

  1. JS常用关键字总结

    in: 案例1.遍历对象: for(key in obj) { console.info( key+":"+obj[key]; ) }; 案例2.判断对象中是否有属性: " ...

  2. LeetCode 348. Design Tic-Tac-Toe

    原题链接在这里:https://leetcode.com/problems/design-tic-tac-toe/ 题目: Design a Tic-tac-toe game that is play ...

  3. SQL Server 默认跟踪(Trace)捕获事件详解

    SQL Server 默认跟踪 -- 捕获事件详解 哪些具体事件默认跟踪文件能够捕获到? --returns full list of events SELECT * FROM sys.trace_e ...

  4. C# Cef winform 脚本的执行 踩过的坑

    先从后端代码 如何执行js 代码谈起; 一个简单的需求: 在winform上点击一个按钮,实现登录信息的填入 流程: 就是让C#去运行一段脚本,. 运行的方式有两种, 异步与同步, 因为CEF是一帧一 ...

  5. 笔记&想要置顶但懒得置顶的文章目录

    1.\(\text{Markdown&Latex}\)学习笔记 2.一些笔记 3.好东西 4.线段树学习笔记 5.并查集学习笔记 6.友链 7.语录

  6. django_settings源码解析

    目录 配置文件插拔式设计: 简单版: 复杂版 importlib 与`__import__的区别: 配置文件插拔式设计: 项目配置文件插拔式设计: 基于django settings源码实现自己项目配 ...

  7. 20165214 2018-2019-2 《网络对抗技术》Exp7 网络欺诈防范 Week10

    <网络对抗技术>Exp7 网络欺诈防范 Week10 一.实验目标与内容 1.实践目标 理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法 2.实践内容 (1)简单应用SET工 ...

  8. MongoDB查询和sql查询的总结

    查询所有表或集合 sql   show tables mongodb    db.getCollectionNames() 删除集合或表 sql   drop table 表名 mongodb    ...

  9. c# MongoDB分页辅助类,支持多条件查询

    创建一个获取MongoDB数据库实例的类 public class Db { private static IMongoDatabase db = null; private static reado ...

  10. Mercari Price Suggestion in Kaggle

    Mercari Price Suggestion 最近看到了一个竞赛,竞赛的内容是根据已知的商品的描述,品牌,品类,物品的状态等特征来预测商品的价格 最后的评估标准为 平均算术平方根误差Root Me ...