JavaScript中深拷贝与浅拷贝的简介

JavaScript中深拷贝与浅拷贝的简介

基础介绍

  • ECMAScript变量包含两种数据类型的值:基本数据类型和引用数据类型。

  • 基本数据类型:Boolean、Null、Undefined、Number、String、Symbol(ES6新增),名和值都存在栈内存中。

  • 引用数据类型:Object、Array、Function 、Data、RegExp等,名存在栈中,值存在堆中,栈内存会提供一个引用地址指向堆中内存中的值。

  • 浅拷贝: 用在引用数据类型赋值后,受原数据影响到赋值操作。也就是说从一个变量给另一个新变量复制引用类型的值,其实复制的就是指针,最终两个变量都指向同一个对象。再通俗的一个例子就是,一个人站在太阳底下,这个人动了,他的影子也动了。

  • 深拷贝:用在基本数据类型赋值后,不受原数据影响到赋值操作。也就是说一个变量给另一个新变量复制基本类型的值,是把这个值给了新变量,相当于把这个值去创建一个副本给了新变量。通俗的一个例子就是,路人乙建了一栋别墅,路人甲也去建了一栋一摸一样的,如果他们去装修,两栋别墅各自发生变化,但二者互不影响。

深浅拷贝的实现

深拷贝

let a = 1;
let b = a; // 新开一个空间然后赋值为1,
a = 2
console.log(a); // 2
console.log(b); // 1
复制代码

image.png

浅拷贝

  • 这个时候无论改变d或者c中的name属性值,二者都将做出相同的变动,因为他们访问的地址是同一个地址。
function foo() {
  var a ='甲'
  var b = a
  var c = {name :'乙'}
  var d = c
  console.log(d); // {name :'乙'}
}
foo()
复制代码

image.png

  • null清除了a的指针,也就是栈中a变量值(地址),但是这并不会影响b
let a = {name: "薛之谦"}
let b = a;
a = null
console.log(a); //null
console.log(b);  // {name: "薛之谦"}
复制代码

小拓展

JavaScript堆不需要程序代码来显示地释放,因为堆是由自动的垃圾回收来负责的,每种浏览器中的JavaScript解释引擎有不同的自动回收方式

一个最基本的原则是:如果栈中不存在某个对象的引用,那么就认为该对象已经不再需要,在垃圾回收时就会清除该对象占用的内存空间。

因此,在不需要时应该将对象的引用释放掉,以利于垃圾回收,这样就可以提高程序的性能。

猜你喜欢

转载自juejin.im/post/7041588937315319845
今日推荐