变量和作用域的小结

有代码如下:

var a = 5;

function A(){

  alert(a);

  var a = 10;

  alert(this.a);

}

new A();

结果: undefined  undefined

 

第一个是变量提升,相当于

var a = 5;

function A(){

  var a ;

  alert(a);    //undefined

  a = 10;   //L3

  alert(this.a);

}

new A();

 

第二个,首先声明a是一个全局变量,函数A中又声明了一个局部变量,所以在函数中L3以后访问a时,a的值应该是10。但此时,访问的是一个this.a,则说明访问的是A函数的属性a,但A只有变量a并没有属性a,所以返回undefined。

既然提到了这里,就总结一下有关变量和作用域的知识点。

 

引用类型的值是对象,保存在堆内存中;基本类型的值在内存中占固定大小空间,被保存在栈内存中。

所以基本类型的复制,复制的是值,而引用类型的复制,其实是包含引用类型值的变量的复制,由于该变量存放的是一个指向对象的指针,所以对该变量的复制即得到这个指针的副本。

 

当对函数进行参数传递时,都是安值传递。基本类型传递过去后,参数保留基本类型值的一个副本,而引用类型传递过去后,参数保存的时引用类型的地址。当参数对对象进行操作时,是通过参数保存的引用类型的地址找到引用类型,再通过引用类型的指针操作对象。

 

我们都知道当函数执行完后,函数里面的局部变量马上就被销毁了。这是因为js的垃圾回收机制。

关于垃圾回收机制,主流用的最多的是标记清除。也就是先给内存中所有变量添加标记,然后去掉在当前执行环境中的变量以及被当前执行环境引用的变量,最后垃圾回收机制会销毁那些带标记的值并回收空间。

基于这个机制,我们很容易得知,因为当前函数执行完后,函数的执行环境从栈中弹出,那么函数中的局部变量被加上标记,最后清楚。

 

还有一种引用计数法,但他容易造成内存泄漏。简单的说,就是由于循环引用,使得某些引用类型值无法自己达到0,并且没有手动断开连接,造成永远无法回收内存,造成的内存泄漏。

 

posted @ 2015-07-02 00:30  锦衣夜行4.2  阅读(156)  评论(0编辑  收藏  举报