数据在内存中的存放以及原生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

回到顶部