js-- 堆栈内存关系

1、栈(stack)堆(heap)

  stack为自动分配的内存空间,它由系统自动释放;

  而heap则是动态分配的内存,大小不定也不会自动释放。

2、基本类型和引用类型

  基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。

  5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。

  引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。

  当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

3、传值与传址

    var a = [1,2,3,4,5];
    var b = a;
    var c = a[0];
    alert(b);//1,2,3,4,5
    alert(c);//1
    //改变数值        
    b[4] = 6;
    c = 7;
    alert(a[4]);//6
    alert(a[0]);//1

a-b:传址   a-c:传值

  

3、浅拷贝

  前面已经提到,在定义一个对象或数组时,变量存放的往往只是一个地址。当我们使用对象拷贝时,如果属性是对象或数组时,这时候我们传递的也只是一个地址。因此子对象在访问该属性时,会根据地址回溯到父对象指向的堆内存中,即父子对象发生了关联,两者的属性值会指向同一内存空间。

 

   let a = {
      key1: 111
    }
    function shallowCopy(p){
      let c = {}
      for(let i in p){
        c[i] = p[i]
      }

      return c
    }
  
    a.key2 = ['a','b']
    let b = shallowCopy(a)
    b.key3 = 333

    console.log('a', a)
    /** a:key1:111
          key2:['a','b']
          */
    console.log('b', b)
    /** b:key1:111
          key2:['a','b']
          key3:333
        */ 

    /**浅拷贝: 为b添加新属性,并未影响到a*/

    /**修改一下a的数组*/
    b.key2.push('c')

    console.log('a.key2',a.key2)
    /**
      a.key2:['a','b','c']
  a中key2也发生了改变
*/

 

原因是key1的值属于基本类型,所以拷贝的时候传递的就是该数据段;但是key2的值是堆内存中的对象,所以key2在拷贝的时候传递的是指向key2对象的地址,无论复制多少个key2,其值始终是指向父对象的key2对象的内存空间。

4、深拷贝

或许以上并不是我们在实际编码中想要的结果,我们不希望父子对象之间产生关联,那么这时候可以用到深拷贝。既然属性值类型是数组和或对象时只会传址,那么我们就用递归来解决这个问题,把父对象中所有属于对象的属性类型都遍历赋给子对象即可。


let a = {
      key1: 111
    }
a.key2 = ['a','b']
function deepCopy(p,c){
      let c2 = c ||{};
      for(let i in p ){
        if(typeof p[i] === 'object'){
          c2[i] = (p[i].constructor === Array) ? [] : {}
          deepCopy(p[i],c2[i])
        }else{
          c2[i] = p[i]
        }
      }
      return c2
    }
    let d = {}
    d = deepCopy(a , d)
    d.key2.push('d')

    console.log('a.key2',a.key2) //a.key2: ["a", "b", "c"]
    console.log('d.key2',d.key2) //d.key2: ["a", "b", "c", "d"]
/**新生成的子对象并没有影响父对象*/
 

 

 

posted @ 2018-01-18 18:05  Caraxiong  阅读(247)  评论(0编辑  收藏  举报