js中闭包
var name = "Microsoft";
function funcA(){
var name = "Google";
alert(name);
return function(){
name = "Facebook";
alert(name);
};
}
var o = funcA(); //Google
alert(name); //Microsoft
o(); //Facebook
******************
执行完后,执行流就会离开funcA, 那么funcA的变量对象就应该被销毁了。
作用域链的创建规则是复制上一层环境的作用域链,并将指向本环境变量对象的指针放到链首;
******************
匿名函数的作用域链应该有三个元素,第一个是匿名函数的变量对象指针,第二个是funcA的变量对象指针,第三个是全局变量对象指针。根据搜索算法,首先搜索匿名函数的变量对象,显然这个对象中不存在name,然后搜索funcA的变量对象,这里面有个“name”,因此将其作为name变量返回,搜索终止,所以,匿名函数引用的是funcA内定义的“name”变量而非全局变量。
var o = funcA();
执行完后,执行流就会离开funcA, 那么funcA的变量对象就应该被销毁了,funcA内定义的变量name就应该不存在了,为什么在后面还可以访问到呢?要解释这个问题,请回想上文一句话:作用域链的创建规则是复制上一层环境的作用域链,并将指向本环境变量对象的指针放到链首;根据这句话我们知道匿名函数的作用域链有三个元素,引用了三个变量对象(上文有说),这里要注意,返回的匿名函数赋值给了变量o,而变量o是一个全局变量,在funcA执行完成后不会被销毁。当赋值的时候,匿名函数的作用域链已然建立,并且此作用域链引用了funcA的变量环境,因此,当funcA执行完毕后,其执行变量和作用域链确实被销毁了,但是其变量对象没有被销毁,因为匿名函数的作用域链对其有引用,其无法被垃圾回收机制销毁。当funcA执行完成后funcA的Scope chain早就销毁了,但是其变量对象(红色表示),因为被匿名函数的Scope chain引用了,所以没有销毁。因此,匿名函数可以访问其成员,当匿名函数执行完成后,它会连同匿名函数的Scope chain一起被销毁。
闭包就是能访问另一个函数作用域中变量的函数。
因为闭包通常通过匿名函数实现,所以经常有人将闭包和匿名函数两个名词混用。闭包的优点很明显,就是可以访问另一个函数域中的变量,缺点也明显,比较耗内存(因为同时保持了N个变量对象)。
var name = "Microsoft";
function funcA(){
var name = "Google";
alert(name);
return function(){
name = "Facebook";
alert(name);
};
}
var o = funcA(); //Google
alert(name); //Microsoft
o(); //Facebook
******************
执行完后,执行流就会离开funcA, 那么funcA的变量对象就应该被销毁了。
作用域链的创建规则是复制上一层环境的作用域链,并将指向本环境变量对象的指针放到链首;
******************
匿名函数的作用域链应该有三个元素,第一个是匿名函数的变量对象指针,第二个是funcA的变量对象指针,第三个是全局变量对象指针。根据搜索算法,首先搜索匿名函数的变量对象,显然这个对象中不存在name,然后搜索funcA的变量对象,这里面有个“name”,因此将其作为name变量返回,搜索终止,所以,匿名函数引用的是funcA内定义的“name”变量而非全局变量。
var o = funcA();
执行完后,执行流就会离开funcA, 那么funcA的变量对象就应该被销毁了,funcA内定义的变量name就应该不存在了,为什么在后面还可以访问到呢?要解释这个问题,请回想上文一句话:作用域链的创建规则是复制上一层环境的作用域链,并将指向本环境变量对象的指针放到链首;根据这句话我们知道匿名函数的作用域链有三个元素,引用了三个变量对象(上文有说),这里要注意,返回的匿名函数赋值给了变量o,而变量o是一个全局变量,在funcA执行完成后不会被销毁。当赋值的时候,匿名函数的作用域链已然建立,并且此作用域链引用了funcA的变量环境,因此,当funcA执行完毕后,其执行变量和作用域链确实被销毁了,但是其变量对象没有被销毁,因为匿名函数的作用域链对其有引用,其无法被垃圾回收机制销毁。当funcA执行完成后funcA的Scope chain早就销毁了,但是其变量对象(红色表示),因为被匿名函数的Scope chain引用了,所以没有销毁。因此,匿名函数可以访问其成员,当匿名函数执行完成后,它会连同匿名函数的Scope chain一起被销毁。
闭包就是能访问另一个函数作用域中变量的函数。
因为闭包通常通过匿名函数实现,所以经常有人将闭包和匿名函数两个名词混用。闭包的优点很明显,就是可以访问另一个函数域中的变量,缺点也明显,比较耗内存(因为同时保持了N个变量对象)。