JS 基础篇(八) 深拷贝与浅拷贝

news/2024/7/19 16:34:29 标签: object, js, javascript, 前端

前提

  1. 堆栈的概念
js">在javascript中,Object,Array,Function是放到堆中,
Number,String,Null,Boolean存放在栈中
  1. 指针
js">个人理解像一个内存地址,指向了数据存放的堆中
  1. 数据存储
    在这里插入图片描述

关于堆栈以后会细说

浅拷贝

浅拷贝就是赋值了一份内存地址而已,而内存中的数据并没有复制一份,
任何一个数据改变两个数据都会改变
看图:
在这里插入图片描述

js">let obj = {a:1,b:2}
let copyObj = obj
copyObj.a = 'kk'
console.log(obj)
//{a:'kk,b:2}
  1. Object.assign(对象里包含引用类型 -->浅拷贝)
js">let objD = { a: 1, b: {a:1,b:2}}
let assignCopy = Object.assign({},objD)
assignCopy.b.a = 'change'
console.log(objD.b.a);
console.log(objD);
console.log(assignCopy);
//change
//{ a: 1, b: { a: 'change', b: 2 } }
//{ a: 1, b: { a: 'change', b: 2 } }
  1. Array.prototype.slice() 和Array.prototype.concat()
js">/**
 * 当对象包含 引用类型
 * slice  concat 浅拷贝
 */
let arrL = [1, { a: 1, b: 1 }]
let sliceArrL = arrL.slice(0)
sliceArrL[1].a = 'slice change'
console.log(arrL);
console.log(sliceArrL);
let concatArrL = Array.prototype.concat.call([],arrL)
concatArrL[1].a = 'concat change'
console.log(arrL);
console.log(sliceArrL);
console.log(concatArrL);

深拷贝

在这里插入图片描述

  1. Object.assign(对象里不包含引用类型–>深拷贝)
js">let objL = { a: 1, b: 2 }
let copyObjL = Object.assign({},objL)
copyObjL.a = 'change'
console.log(objL);
console.log(copyObjL);
//{ a: 1, b: 2 }
//{ a: 'change', b: 2 }
  1. Array.prototype.slice() 和Array.prototype.concat()
js">/**
 * 当对象不包含 引用类型
 * slice  concat 深拷贝
 */
let arrL = [1, 2]
let sliceArrL = arrL.slice(0)
sliceArrL[1]= 'slice change'
console.log(arrL);
console.log(sliceArrL);
//[ 1, 2 ]
//[ 1, 'slice change' ]
let concatArrL = Array.prototype.concat.call([],arrL)
concatArrL[1] = 'concat change'
console.log(arrL);
console.log(sliceArrL);
console.log(concatArrL);
//[ 1, 2 ]
//[ 1, 'slice change' ]
//[ 1, 'concat change' ]
  1. JSON.parse()和JSON.stringify()
js">/**
 * 当对象不包含 引用类型
 * json.stringify json.parse
 */
let obj = { a: 1, b: {a:1,b:2}}
let copyObj = JSON.parse(JSON.stringify(obj))
obj.b.a = 'change'
console.log(obj);
console.log(copyObj);

let arr = [1, { a: 1, b: 2 }]
let copyArr = JSON.parse(JSON.stringify(arr))
arr[1].a = 'change'
console.log(arr);
console.log(copyArr);
/*
*	不能复制function  正则 日期对象,
*	相同引用会重复复制	
*/
let tempObj = {a:'zzz'}
let obj = {
  syb: Symbol('kk'),
  fn: () => {console.log('kk')},
  reg: /^0-9$/,
  a:'string',
  obj1:tempObj,
  obj2:tempObj
}
let copyObj = JSON.parse(JSON.stringify(obj))
tempObj.a = 'change'
console.log(obj)

copyObj.obj1.a = 'change'
//copyObj.fn() //不能复制方法
console.log(copyObj);

手动递归实现

注意:这里没有处理日期,function,symbol,正则的拷贝

js">let obj = {
  arr: [1, 2, 3],
  obj: {a:1,b:2}
}

function judgeType(target) {
  return Object.prototype.toString.call(target).slice(8,-1)
}

function deepClone (target) {
  let result,targetType = judgeType(target)
  if (targetType !== 'Object' && targetType !== 'Array') return target
  if (targetType === 'Object') { result = {}}
  if (targetType === 'Array') { result = [] }
  for (const key in target) {
      let val = target[key]
      if (judgeType(val) === 'Object' || judgeType(val)==="Array") {
        result[key] = deepClone(val)
      } else {
        result[key] = val
      }
  }
  return result
}
let copyObj = deepClone(obj)
obj.arr[0] = 'change'
console.log(obj);
console.log(copyObj);
//{ arr: [ 'change', 2, 3 ], obj: { a: 1, b: 2 } }
//{ arr: [ 1, 2, 3 ], obj: { a: 1, b: 2 } }

http://www.niftyadmin.cn/n/1852507.html

相关文章

ffpmeg参数说明

最近在研究如何将.avi,wmv等文件通过程序自动转为flv文件,结果发现其实是可以的,要搞成不是那么难的,主要是ffpmeg这东西,转了相关的参数如下,方便日后参考ffmpeg.exe -i F:\闪客之家\闪客之歌.mp3 -ab 56 -ar 22050 -…

GZS与小公园(DFS)

Description 某天GZS漫步在学校新建的小公园,他发现那里建成了一些水池和小河道。我们暂且把它们统一看成水池。假设公园旁有一张小公园的地图,上面仅标识了此处是否是水池,你能帮GZS计算出该地图中一共有几个水池吗。 Input 第一行输入一个整…

JS 基础篇(九) 函数防抖和函数节流

函数防抖 函数防抖:高频率触发(比如10分钟内一直触发)的时候,只执行一次,第一次或者最后一次。重点在只执行一次。 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。 应用场景…

c#,随机数,random

摘自:http://www.pcjx.com/Dotnet/C/208333.html我们在做能自动生成试卷的考试系统时,常常需要随机生成一组不重复的题目,在.net Framework中提供了一个专门用来产生随机数的类System.Random。对于随机数,大家都知道,计…

beautifulsoup库的使用

beautifulsoup库的使用 beautifulsoup就是一个非常强大的工具,爬虫利器。 beautifulSoup “美味的汤,绿色的浓汤” 一个灵活又方便的网页解析库,处理高效,支持多种解析器。利用它就不用编写正则表达式也能方便的实现网页信息的抓取…

JS 基础篇(十) cookie封装

cookie简单介绍 cookie的特点1.cookie一般有大小限制为4kb, 2.限制同一域名数量为50个 3.读取有域名限制 4.时效性cookie 使用//添加cookie document.cookie “keyvalue”; // 一次写入一个键值对 //读取cookie document.cookie //获得所有cookie 分号分割//exp…

layui + thymeleaf 动态拼接地址

1.第一种方式 {url}进行占位&#xff0c;在后面的()里写入占位的值 ${url}是controller里面传过来的值<img th:src"{{url}{{d.userImg}}(url${url})}" alt"加载失败"/>2.第二种方式 {{d.userImg}} 是layui的获取全局变量里的值&#xff0c;用单引号…

《末代皇帝》原声音乐《where is armo?》

[hjp3]hjptypesong&player6&sw1http://www.justrun.net/misc/whereisarmo.mp3&autoplayfalse&width380&height90[/hjp3] 转载于:https://www.cnblogs.com/JemBai/archive/2008/07/18/1245877.html