数据在内存中的存放以及原生JS实现深拷贝
堆和栈
在 JavaScript 的执行过程中, 主要有三种类型内存空间,分别是代码空间、栈空间和堆空间。其中的代码空间主要是存储可执行代码的,栈和堆用来存放数据。
其中,原始类型的数据值都是直接保存在“栈”中的,引用类型的值是存放在“堆”中的。通常而言,栈空间都不会设置太大,主要用来存放一些原始类型的小数据。而引用类型的数据占用的空间都比较大,所以这一类数据会被存放到堆中,堆空间很大,能存放很多大的数据。不过缺点是分配内存和回收内存都会占用一定的时间。
在 JavaScript 中,赋值操作和其他语言有很大的不同,原始类型的赋值会完整复制变量值,而引用类型的赋值是复制引用地址。 原始类型的数据是存放在栈中,引用类型的数据是存放在堆中的。堆中的数据是通过引用和变量关联起来的。
下面有个例子
functionfoo(){var a = "ant"
var b = a
var c = { name : "ant" }
var d = c
}
foo()
在内存中,存放的入下图所示:
c与d是同一个引用,指向相同的地址,只要其中任何一个改动了name的属性,另外一个也会发生相应的变化。
深拷贝浅拷贝的区别
浅拷贝: 将内存中的某个对象复制一份,在内存中开辟一块新的空间,如果复制的这个对象的属性为基本数据类型 ,则拷贝的便为这个值本身,如果为复杂数据类型,则拷贝复制的为地址,因此,修改新对象会对原对象产
生影响。
深拷贝:开辟一块新的空间,完整的复制一份,包括复杂数据类型,拷贝的这个对象和原对象无任何关系,修改什么 的都互不影响。
深拷贝的实现
首先写一段基础的深拷贝代码:
function deepClone(obj) {if (typeof(obj) !=="object") {
return obj
} else {
let newObj = {}
for (let key in obj) {
newObj[key] = deepClone(obj[key])
}
return newObj
}
}
这代码实现了一个基础的深拷贝,但是对于一些特殊情况还是没法解决,例如当obj是null,是Date类型,RegExp类型或者是数组。所以更改一下代码,将这些特殊情况弄出来。
function deepClone(obj) {if (obj === null) return null //null
if (obj instanceof RegExp) return new RegExp(obj) //RegExp
if (obj instanceof Date) return new Date(obj) //Date
if (typeof(obj) !=="object") {
return obj
} else {
let newObj = new obj.__proto__.constructor //Array或者Object
for (let key in obj) {
newObj[key] = deepClone(obj[key])
}
return newObj
}
}
测试一下:
let src = {name: "ant",
date: new Date(),
reg: /^666$/,
arr: ["a", "n", "t"],
info: {
age: 999,
job: "developer"
}
}
let target = deepClone(src)
console.log(target)
结果:
以上就是一个深拷贝的实现,如果有漏洞,请留言补充!
以上是 数据在内存中的存放以及原生JS实现深拷贝 的全部内容, 来源链接: utcz.com/a/34419.html