JS 中的数据类型可分为两种:
undefined
, null
, Boolean
, String
, Number
, Symbol
Object
, Array
, Date
, Function
, RegExp
等不同类型的存储方式:
栈内存
中堆内存
中,而 栈内存
中存储的是对象的 变量标识符
以及对象在 堆内存
中的存储地址不同类型的复制方式:
对象的浅拷贝是属性与拷贝的源对象属性共享相同的引用(指向相同的底层值)的副本。因此,当你更改源对象或副本时,也可能导致另一个对象发生更改。与之相比,在深拷贝中,源对象和副本是完全独立的。
function shallowClone(object) {
// 只拷贝对象
if (!object) return object
// 根据 object 的类型判断是新建一个数组还是对象
const newObject = Array.isArray(object) ? [] : {}
// 遍历 object,并且判断是 object 的属性才拷贝
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key]
}
}
return newObject
}
const obj = {
a: 'hello',
b: {
c: 'js',
},
}
const newObj = shallowClone(obj)
newObj.a = 'HELLO'
newObj.b.c = 'JS'
console.log(obj.a) // => hello
console.log(obj.b.c) // => JS
const obj = {
a: 'hello',
b: {
c: 'js',
},
}
const newObj = Object.assign({}, obj)
newObj.a = 'HELLO'
newObj.b.c = 'JS'
console.log(obj.a) // => hello
console.log(obj.b.c) // => JS
const obj = {
a: 'hello',
b: {
c: 'js',
},
}
const newObj = { ...obj }
newObj.a = 'HELLO'
newObj.b.c = 'JS'
console.log(obj.a) // => hello
console.log(obj.b.c) // => JS
在 JavaScript 中,深克隆是指对一个对象或数组进行完整的拷贝,包括嵌套的对象和数组。深克隆的实现有多种方式,具体选择取决于数据结构的复杂程度和性能要求。
const obj = {
a: 'hello',
b: {
c: 'js',
},
}
const newObj = JSON.parse(JSON.stringify(obj))
newObj.a = 'HELLO'
newObj.b.c = 'JS'
console.log(obj.a) // => hello
console.log(obj.b.c) // => js
局限性:
会忽略 undefined 会忽略 symbol 不能序列化函数 不能解决循环引用的对象
function deepClone(obj) {
if (obj === null) return obj
if (obj instanceof Date) return new Date(obj)
if (obj instanceof RegExp) return new RegExp(obj)
if (typeof obj !== 'object') return obj
const cloneObj = new obj.constructor()
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key])
}
}
return cloneObj
}
const obj = {
a: 'hello',
b: {
c: 'js',
},
}
const newObj = deepClone(obj)
newObj.a = 'HELLO'
newObj.b.c = 'JS'
console.log(obj.a) // => hello
console.log(obj.b.c) // => js
局限性:
有爆栈的风险 大对象性能问题 循环引用
全局的 structuredClone() 方法使用结构化克隆算法将给定的值进行深拷贝。
const obj = {
a: 'hello',
b: {
c: 'js',
},
}
const newObj = structuredClone(obj)
newObj.a = 'HELLO'
newObj.b.c = 'JS'
console.log(obj.a) // => hello
console.log(obj.b.c) // => js