「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」
浅拷贝
介绍
浅拷贝 ,通过名字可以知道,是进行拷贝某种东西。
浅拷贝 但是为什么加个浅,是由于js的 基本类型 和 引用类型 存放的位置不同,在拷贝时也就会出现不同的 拷贝 模式。
浅拷贝 如果拷贝的是基本数据类型,拷贝的就是基本数据类型的值,如果是引用数据类型,拷贝的就是内存地址。
浅拷贝
-
由于js的 基本类型 存放在 栈内存中
数据的大小确定,按值进行存放,可以直接进行访问,而且基本数据类型 值是不可变的。
let str = '123' str[1] = '4' console.log(str) console.log(str[1])
结果为:
'123' '2'
你可能会好奇,那如果是 布尔值 或者是 数值 类型的呢?
其实是一样的,只不过,我们更改后,那叫对这个变量 重新赋值,而不是改变基本数据类型的值。例如
let str = 123 let str2 = true str = true str2 = 123 console.log(str) console.log(str2)
结果为:
true 123
-
但是 引用类型 的存放 是在 堆内存 中
数据大小不确定,要根据不同的情况来进行不同的分配。
通常我们 将设置一个指向该 数据地址 的指针,而将该指针放入 栈内存 中。我们访问该指针变量,即可得到该引用类型的数据
经典的就是下面的代码
const a = [1,2,3] const b = [1,2,3] console.log(a === b)
结果为: false
const a = [1,2,3] const b = a b[0] = 2 console.log(a) console.log(b) console.log(a===b)
结果为:
[ 2, 2, 3 ] [ 2, 2, 3 ] true
-
浅拷贝
-
Object.assign()
es6中的对象拷贝,是一种浅拷贝方式
用法:object.assign(target,source_1,···)
const a = { a: 1, b: { bb: true } } const b = { c: 2, d: { dd: false } } Object.assign(a,b) console.log(a) console.log(b) b.c=3 b.d.dd = true console.log(a) console.log(b)
结果为
{ a: 1, b: { bb: true }, c: 2, d: { dd: false } } { c: 2, d: { dd: false } } { a: 1, b: { bb: true }, c: 2, d: { dd: true } } { c: 3, d: { dd: true } }
可以看到可以这个仅仅对第一层进行拷贝,而并没有对第二层对象进行拷贝。
-
手写浅拷贝
const shallowCopy = (object) => {
// 只拷贝对象
if (!object || typeof object !== 'object') return
// 判断是数组还是对象
let newObject = Array.isArray(object) ? [] : {}
// 遍历 object,并且判断是 object 的属性才拷贝
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key]
}
}
return newObject
}
总结
浅拷贝 对基本数据类型,拷贝的就是基本数据类型的值
对引用数据类型,拷贝的是内存地址