js中的数据存储与拷贝

221 阅读2分钟

很无聊,好久不更新了,今天来说下拷贝问题。

js中数据的存储

js中有两种数据类型,基本类型和引用数据类型,可以看这里js中的数据类型。 它们在内存中的存储方式也不相同。 代码执行,开辟新的内存空间,基本类型可以理解为以它的真实值的方式存储在栈内存中。而复杂的引用类型,则会开辟块单独的堆内存来做数据存储,在执行栈中存储的只是这个堆的内存地址,就是堆的引用。

const a = 5
const ob = {
    a: 5,
    c: 7
}
/**
代码执行,a存储的值是5,
而对象 {a: 5,c: 7}则开辟了一块堆内存进行存储,假设堆内存地址是AAAFFF,则变量ob存储的值就是AAAFFF
**/

浅拷贝 && 深拷贝

在拷贝引用类型的时,假如只是简单的赋值:

const ob = { a: 5, c: 7 } //假设地址时AAAFFF
const ob2 = ob //将地址AAAFFF赋予ob2

ob2.a = 8
console.log(ob) // { a: 8, c: 7 }

那么只是将ob指向的地址赋予了ob2,堆内存中的a发生了改变,地址未改变,ob和ob2仍然指向AAAFFF,指向同一块地址的两个变量实际为同一个。这就是浅拷贝。

若只是基本数据类型的赋值,是直接将值赋给新变量,并不存在地址问题,原变量不受影响。我们可以根据这点来实现个不会受影响的深拷贝:

const ob = { a: 5, c: 7 }
const ob2 = {} //开辟新的与ob无关的内存空间
for(key in ob){
    ob2[key] = ob[key]
}
ob2.a = 9
console.log(ob.a) //5
console.log(ob2.a) //9

其他通用深拷贝方法可以用递归实现,这里就不写了。

其他

  • const定义常量:变量存储的值不变。如果是引用来类型,堆内存里发生的改变,不影响地址变动,const定义的常量为改变
  • 说是那么说,理解上基本类型存储的是真实值,但js中的基本类型上仍有许多继承下来的方法,并不是单纯的就只有存一个值。