JavaScript中的闭包:
1)概念:有权访问另一个函数作用域中的变量的函数。
2)创建方式:在一个函数内部创建另一个函数,最常见的是在函数中返回一个匿名函数。
3)特点:匿名函数的执行环境具有全局性,它会携带包含它的外部函数的作用域,并且把外部函数中的局部变量驻留在内存中。
优点:可以避免使用全局变量。(全局变量污染导致应用程序不可预测性,每个模块都可调用的全局变量必将引来灾难,所以推荐使用私有的、封装的局部变量)。
缺点:闭包会携带包含它的函数的作用域,因此会比其它函数占用更多的内存,所以使用闭包时要慎重。
4)闭包访问变量的顺序:闭包中的局部变量、外部函数的局部变量、全局变量。
5)经典的例子:
例子一:
function a(){
var a = "a";
return function(){ //通过匿名函数访问a()中的局部变量
return a + "b";
}
}
alert(a()()); // ab
例子二:
var b;
function a(){
var a = "a";
b = function(){
return a + "b";
}
return a;
}
//测试
alert(a()); // a
alert(b()); // ab
说明:
在a()函数中定义了b()函数,所以b()函数可以访问a()函数的作用域。
将b()函数升级到全局函数,但依然保留可以对a()函数作用域的访问权
例子三:循环中的闭包
function f(){
var a = [];
var i;
for(i = 0; i < 3; i++){
a[i] = function(){
return i;
}
}
return a;
}
var fun = f();
alert(fun[0]()); //output 3
alert(fun[1]()); //output 3
alert(fun[2]()); //output 3
按照预期,最终结果应该分别输出0,1,2,然而事实上却是3,3,3
分析:
1)在函数f()中,通过for循环创建了三个闭包,它们都返回了共同的局部变量i。
2)闭包并不会记录局部变量i的值,它们所拥有的只是局部变量i的一个引用,因此只能返回局部变量i的最后一个值!!!
注意:
1)闭包不是所在(函数)对象的属性或方法。
2)闭包会携带包含它的函数的作用域,因此会比其它函数占用更多的内存,所以使用闭包时要慎重。
例子四:利用闭包的概念,实现Getter与Setter功能。
//假设现在有一个特殊的变量secret,不想暴露给外部。
var getValue, setValue;
(function f(){
var secret = 0;
getValue = function (){
return secret;
}
setValue = function (x){
secret = x;
};
})();
getValue(); //output 0
setValue(123);
getValue(); //output 123
JavaScript中的闭包
最新推荐文章于 2024-11-10 12:03:31 发布