为什么会用到浅拷贝和深拷贝

首先来看一下如下代码

let a = b = 2
a = 3
console.log(a)
console.log(b)
let c = d = [1,2,3]
let e = f = {a:1,b:2,c:3}
c[0] = 2
e.a = 2
console.log(d[0])
console.log(f.a)

你会发现,同一个Array或者Object赋值给两个不同变量时,变量指向的是同一个内存地址,所以就会造成其中一个变量改变属性值,同时改变了另外一个变量的对应属性值。

而大多数实际项目中,我们想要的结果是两个变量(初始值相同)互不影响。所以就要使用到拷贝(分为深浅两种)

深浅拷贝的区别

浅拷贝只复制一层对象的属性,而深拷贝则递归复制了所有层级。
浅拷贝有效性针对的是单一层级对象 [1,2,3]或者{a:1,b:2}
深拷贝有效性针对的是单层或者多层级对象 [1,2,3]或者{a:1,b:2}或者[1,[1],{a:1}]或者{a:[1],b:{c:2}}

浅拷贝

  • 如何实现
// 数组
let a = [1,2]
let b = a.slice()
// {}
let e = {a:[1],b:{d:1},2}
let f = Object.create(e)
function shallowCopy (obj) {
if (typeof obj === 'object' && obj !== null) {
if (Array.isArray(obj)) {
return obj.slice()
} else {
let result = {}
Object.keys(obj).forEach((item,i) = > {
console.log(i)
result[item] = obj[item]
})
return result
}
} else {
return obj
}
}
  • 应用场景
    对于一层结构的Array和Object想要拷贝一个副本时使用
    vue的mixin是浅拷贝的一种复杂型式

深拷贝

  • 如何实现
// 利用JSON(它能正确处理的对象是Number, String, Boolean, Array, 扁平对象)
let g = JSON.parse(JSON.stringify(obj))
// 适用于
function deepCopy (obj) {
if (typeof obj === 'object' && obj !== null) {
let objKeys = Object.keys(obj)
let result
if (Array.isArray(obj)) {
result = []
} else {
if (obj.constructor === Object) {
result = {}
} else {
return obj
}
}
objKeys.forEach((item) => {
if (typeof obj[item] === 'object' && obj[item] !== null) {
switch (obj[item].constructor) {
case Array:
result[item] = deepCopy(obj[item])
break
case Object:
result[item] = deepCopy(obj[item])
break
case Date:
result[item] = new Date(obj[item])
break
case RegExp:
let attributes = ''
attributes += obj[item].global ? 'g' : ''
attributes += obj[item].ignoreCase ? 'g' : ''
attributes += obj[item].multiline ? 'g' : ''
result[item] = new RegExp(obj[item].source, attributes);
break
default:
result[item] = obj[item]
break
}
} else {
result[item] = obj[item]
}
})
return result
} else {
return obj
}
}
  • 应用场景
    复制深层次的object数据结构
  • 对深拷贝的应用想法
    在实际工作中是不是用继承来实现更好?需要大家来讨论,提意见

js的浅拷贝和深拷贝和应用场景的更多相关文章

  1. js对象浅拷贝和深拷贝详解

    js对象浅拷贝和深拷贝详解 作者:i10630226 字体:[增加 减小] 类型:转载 时间:2016-09-05我要评论 这篇文章主要为大家详细介绍了JavaScript对象的浅拷贝和深拷贝代码,具 ...

  2. Javascript/js 的浅拷贝与深拷贝(复制)学习随笔

    js变量的数据类型值分基本类型值和引用类型值. 在ES6(ECMAScript6)以前,基本数据类型包括String.Number.Boolean.Undefined.Null. 基本类型值的复制(拷 ...

  3. js实现浅拷贝和深拷贝

    实现浅拷贝和深拷贝 1. 浅拷贝和深拷贝的区别 简单点说,浅拷贝拷贝完后,修改拷贝的内容可能会对源内容产生影响.而深拷贝就是拷贝前后的内容相互不影响.       那为什么拷贝前后的内容会相互影响呢? ...

  4. [转] js对象浅拷贝和深拷贝详解

    本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = ...

  5. js中浅拷贝和深拷贝以及深拷贝的实现

    前言:2019年的第一篇分享... 一.什么是基本类型值和引用类型值?ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型.基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构 ...

  6. 小tips:JS之浅拷贝与深拷贝

    浅拷贝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷贝: functio ...

  7. js相关--浅拷贝和深拷贝

    1.js的数据类型 基本概述:js的数据类型分为两种,分别为基本数据类型和引用数据类型,它们俩的区别在于基本数据类型采用值传递,引用数据类型采用指针形式传递. 如下所示:引用类型通过简单的=进行复制, ...

  8. JS的浅拷贝与深拷贝

    浅拷贝 //这样的拷贝有一个问题.那就是,如果父对象的属性等于数组或另一个对象,//那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能. function exten ...

  9. js之浅拷贝与深拷贝

    浅拷贝:只会复制对象的第一层数据 深拷贝:不仅仅会复制第一层的数据,如果里面还有对象,会继续进行复制,直到复制到全是基本数据类型为止 简单来说,浅拷贝是都指向同一块内存区块,而深拷贝则是另外开辟了一块 ...

随机推荐

  1. 续AspectJ篇

    这篇将介绍AspectJ的第二种开发方法:基于注解的声明式-AspectJ. 与基于代理类的AOP实现相比,基于XML的声明式AspectJ要便捷的多,但是它也存在一些缺点,那就是在Spring文件中 ...

  2. RSA使用

    RSA使用 今天在跟同事一起调试TCP通讯的时候,在RSA私钥解密这块,着实让我费了一番心思. 流程大致是这样的,终端登录的时候使用固定的des密码加密数据发送,平台接收后确认登录信息后,会返回一个字 ...

  3. 基于HttpRunner,解析swagger数据,快速生成接口测试框架

    使用HttpRunner默认生成的项目是这样的 命令:httprunner --startproject  项目名称 so,根据这个项目的目录结构,使用python解析swagger接口参数,可以快速 ...

  4. tp5+layui实现分页

    layui和thinkphp5自己在百度上下载 html代码 <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  5. 用户吐槽不断:Android 10.0没法用

    如果你升级到Android Q第三个测试版的话,那么最近是不是被设备不断重启搞崩溃了,事实上也确实如此,因为有很多用户都遇到了类似的情况,大家吐槽谷歌的声音越来越大. 不少用户发现,自己设备升级至An ...

  6. Linux学习之CentOS(二十六)--Linux磁盘管理:LVM逻辑卷的创建及使用

    在上一篇随笔里面 Linux学习之CentOS(二十五)--Linux磁盘管理:LVM逻辑卷基本概念及LVM的工作原理,详细的讲解了Linux的动态磁盘管理LVM逻辑卷的基本概念以及LVM的工作原理, ...

  7. mysql5.7使用gtid模式搭建主从复制架构

    一.架构 两台mysql服务器做一主一从,172.28.18.69(主) 172.28.18.78(从) 二.分别编译安装mysql5.7 1.下载mysql5.7.26源码包 [root@serve ...

  8. SSH整合——登录模块

    1.导包——参照我的GitHub Hibernate hibernate/lib/required hibernate/lib/jpa 数据库驱动 Struts2 struts-blank.war/W ...

  9. 转载:利用php数组函数进行函数式编程

    因为一个BUG, 我在一个摇摇欲坠,几乎碰一下就会散架的项目中某一个角落中发现下面这样一段代码 这段程序与那个BUG有密切的关系. 我来回反复的捉摸这段代码, 发现这段代码实现了两个功能 第一个是在一 ...

  10. zabbix的简单操作(查看监控,自定义监控和钉钉监控报警)

    zabbix是一种监控软件,我用的是centos7.5版本 一:我已经添加好主机了,接下来就是看看怎么查看监控内容的 1.打开zabbix服务的web网页 2.检测最新数据,要在最新数据中筛选 3.查 ...