作者:zccst
如果您觉得本文的内容对您的学习有所帮助,您可以微信:
[img]http://dl2.iteye.com/upload/attachment/0109/0668/fb266dfa-95ca-3d09-b41e-5f04a19ba9a1.png[/img]
//1,闭包是词法作用域(作用域在定义时决定,不是在调用时决定)
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
};
var r = checkscope()();
console.log(r);//local scope
//2,闭包可以捕捉到单个函数调用的局部变量,并将这些局部变量用做私有状态。
var uniqueInteger = (function(){
var counter = 0;
return function(){
return counter++;
}
}());
//分析:这是一个嵌套的函数。当外部函数返回之后,其它任何代码都无法访问counter变量,只有内部的函数才能访问它。
//引申1:
function counter(){
var n = 0;
return {
count:function(){return n++;},
reset:function(){n=0;}
};
}
var c = counter(), d = counter();
console.log(c.count());//0
console.log(d.count());//0
console.log(c.reset());
console.log(c.count());//0
console.log(d.count());//1
/*
批注:每次调用counter(),都会创建一个新的作用域链和一个新的私有变量。因此,如果调用counter()两次,则会得到两个计算器对象,而且彼此包含不同的私有变量,调用其中一个计数器对象的count()和reset()不会影响到另外一个对象。
*/
//引申2:
function counter(n){
return {
get count(){return n++;},
set count(m){
if(m >= n) n=m;
else throw Error("只能越来越大,不能越来越小");
}
};
}
var c = counter(1000);
console.log(c.count);//1000
console.log(c.count);//1001
c.count = 2000;
console.log(c.count);//2000
c.count = 2000;//Error
/*
批注:这个版本并未声明局部变量,只是使用参数n来保存私有状态,属性存取器方法可以访问n,这样的话,调用counter()的函数就可以制定私有变量的初始值了。
*/
function constfuncs(){
var funcs = [];
for(var i= 0; i<10; i++){
funcs[i] = function(){
return i;
};
}
return funcs;
}
var funcs = constfuncs();
console.log(funcs[5]());//10
/*批注,这些闭包都是在同一个函数调用中定义的,因此他们可以共享变量i。
所有的闭包都共享这一个值,因此数组中的函数的返回值都是同一个值,这不是我们想要的结果。
*/
//还有注意this的关键字,而不是变量。每个函数调用都包含一个this值,如果闭包在外部函数里是无法访问this的,除非外部函数将this转存为一个变量:
var self = this;//将this保存至一个变量中,以便嵌套的函数能够访问它。
如果您觉得本文的内容对您的学习有所帮助,您可以微信:
[img]http://dl2.iteye.com/upload/attachment/0109/0668/fb266dfa-95ca-3d09-b41e-5f04a19ba9a1.png[/img]