网站服务器购买,ftp怎么设置网站首页,网站 验证码 错误,专做毕业设计的网站目录
1 引言
2 浅拷贝
2.1 拷贝数组 1.2 拷贝对象
3 赋值操作和浅拷贝的比较
4 深拷贝
4.1 前置知识 -- 递归函数
4.2 使用递归实现深拷贝
4.3 js库中的lodash里面的cloneDeep内部实现深拷贝
4.4 利用JSON实现深拷贝 深浅拷贝只针对引用数据类型 1 引言
假如我们…目录
1 引言
2 浅拷贝
2.1 拷贝数组 1.2 拷贝对象
3 赋值操作和浅拷贝的比较
4 深拷贝
4.1 前置知识 -- 递归函数
4.2 使用递归实现深拷贝
4.3 js库中的lodash里面的cloneDeep内部实现深拷贝
4.4 利用JSON实现深拷贝 深浅拷贝只针对引用数据类型 1 引言
假如我们想要使用一个对象我们之前通常使用赋值的方式但是使用赋值的方式时修改赋值后的对象中的数据会影响原对象
比如
const obj {name: 张三,age: 18,
}
console.log(obj)
const obj2 obj;
obj2.name 李四
console.log(obj2)
console.log(obj) 而上述的代码只是修改了简单数据类型如果修改复杂数据类型结果更是如此了 2 浅拷贝 浅拷贝遇到复杂的数据类型拷贝的是地址 2.1 拷贝数组
方式一
const arr1 [1, 2, 3]
const arr [...arr1]
console.log(arr)
arr[0] 100
console.log(arr)
console.log(arr1) 方式二
const arr1 [1, 2, 3]
const arr2 arr1.concat()
console.log(arr2)
arr2[0] 100
console.log(arr2)
console.log(arr1) 以上两种方式可以实现单层数组的拷贝那么如果我们遇到嵌套的数组使用这种方式还可以吗 例
const arr1 [1, [1, 2, 3], 3]
const arr2 arr1.concat()
console.log(arr2)
arr2[1][2] 100
console.log(arr2)
console.log(arr1)
此时我们修改拷贝后得到的数组中的数据发现原数组也被修改了。所以当遇到单层的数组时拷贝时数组中只是简单数据类型修改不会影响原数组但是如果是嵌套的数据数组中包含数组那么拷贝是是直接将内层数组作为一个元素拷贝数组属于复杂数据类型所以最终拷贝的是地址。 1.2 拷贝对象
比如以下代码
const obj {name: 张三,age: 18,height: 1.88,family: { father: 李四,mother: 王五}
}
方式一
const o { ...obj }
console.log(o)
o.name 李四
console.log(o)
console.log(obj) 方式二
const o Object.assign({}, obj)
console.log(o)
o.age 20
o.family.father 赵六
console.log(o)
console.log(obj) 在上面的这段代码中我们修改拷贝后的对象中的复杂数据类型结果如下 3 赋值操作和浅拷贝的比较
1、直接赋值的方式只要是对象都会相互影响因为都是直接拷贝的是栈中的地址。
2、浅拷贝如果是一层对象不会相互影响如果出现多层对象还是会相互影响。因为如果拷贝的对象中是简单数据类型直接拷贝的是值如果是复杂数据类型拷贝的还是地址
--- 浅拷贝在直接赋值的不足之处进行了改进而浅拷贝同样也是需要改进接下来将介绍深拷贝将解决浅拷贝的不足之处 4 深拷贝
4.1 前置知识 -- 递归函数
首先递归函数是什么简单理解就是自己调用自己。
1 例实现阶乘
【代码】
function fn(n) {if (n 1)return 1return n * fn(n - 1)
}
const re fn(5)
console.log(re)
2 案例利用递归函数实现setTimeout 模拟setInterval效果
【代码】
function getTime() {document.querySelector(div).innerHTML new Date().toLocaleString()setTimeout(getTime, 1000)
}
getTime() 4.2 使用递归实现深拷贝
const obj {name: 张三,age: 18,hobby: [学习, 喝酒, 烫头],family: {father: 张三丰,mother: 张三娘}
} 【需求】现在需要拷贝上述 obj 对象中的所有数据并且修改拷贝后的对象不管修改的是简单数据类型还是复杂数据类型都不会影响原对象
const obj1 {}// 拷贝函数
function deepClone(obj1, obj) { // onj1是新对象 obj是旧的for (let key in obj) {// 处理数组的问题if (obj[key] instanceof Array) {obj1[key] []deepClone(obj1[key], obj[key])} else if (obj[key] instanceof Object) { // 处理对象的问题 因为arr 也属于对象 所以判断对象时写在后面obj1[key] {}deepClone(obj1[key], obj[key])} else { // 处理其他数据类型的问题obj1[key] obj[key]}}
}deepClone(obj1, obj)
obj1.age 30
obj1.hobby[0] 睡觉
console.log(obj1)
console.log(obj) 4.3 js库中的lodash里面的cloneDeep内部实现深拷贝
1. 首先引入lodash.js文件 也可以使用 npm 直接安装
$ npm i -g npm
$ npm i --save lodash
2 【代码】
const obj {name: 张三,age: 18,height: 1.88,family: { // 遇到这种复杂数据类型拷贝的还是地址 修改会相互影响father: 李四,mother: 王五}
}const obj1 _.cloneDeep(obj)
obj1.family.father 赵六
console.log(obj1)
console.log(obj) 虽然使用js自带的库实现深拷贝比递归的方式简单多了但是还用引入文件也挺麻烦的接下来再介绍一种更简单的方式。 4.4 利用JSON实现深拷贝
【代码】
const obj {name: 张三,age: 18,height: 1.88,family: { father: 李四,mother: 王五}}const obj1 JSON.parse(JSON.stringify(obj)) // 先拿到的是字符串属于简单数据类型直接存值console.log(obj1)
obj1.family.father 赵六
console.log(obj1)
console.log(obj) 注意JSON.stringify()只能处理对象和数组不能处理函数