标签:
有代码如下:
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,并且没有手动断开连接,造成永远无法回收内存,造成的内存泄漏。
标签:
原文地址:http://www.cnblogs.com/julyys/p/4614945.html