阮一峰大神对闭包的解释 我对闭包的理解就是:一个可以访问另一个作用域中变量的函数,闭包函数就是起一个桥梁作用,在作用域链中的反映就是给两个作用域连了一条线,运行闭包函数的父函数可以访问闭包所在的子函数的变量;
闭包函数的活动对象包括它涉及到所有变量对象所在函数的活动对象即作用域,并且如果已经赋值,也会一并带出去,除了this是特例;注意,这里如果一个变量有多个值,只会取最后一个,见下面的for循环;
例如:这里面的匿名函数是一个闭包,它涉及到了f1函数的变量a,f2函数的变量b;在全局中调用时,它打印的是它原本的父函数们中的变量对象a,b;而不是全局变量a,b;
var a = 1;
var b = 1;
function f1(){
var a = 2;
function f2(){
var b = 2;
return function(){
// return a;//2
// return b;//2
console.log("我是f1的a:"+ a +" 我是f2的b:"+ b);
};
};
return f2;
}
f1()()();
结果:
与for循环一起用
function createFunction1(){
var result1 = new Array();
for(var i = 0;i<10;i++){
result1[i] = function(){
return i;
}
}
return result1;
}
var arr1 = createFunction1();
for (var i=0; i < arr1.length; i++){
document.write(arr1[i]() + "<br />");
}//打印的都是10因为,这里返回的函数中调用都是i而且是for循环结束之后的i
//结果:10101010101010101010
function createFunction2(){
var result2 = new Array();
for(var i = 0;i<10;i++){
result2[i]=function(num){
return function(){
return num;
}
}(i);
}
return result2;
}
var arr2 = createFunction2();
//arr2里面是函数,且函数里面是num,不是i
for (var i=0; i < arr2.length; i++){
document.write(arr2[i]() + "<br />");
}
//结果:0123456789
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());//The Window
这里就涉及到上面说的特例:this。
this对象是运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。《Javascript高级程序设计》
其实最后的 object.getNameFunc()() 这里相当于:
var first = object.getNameFunc;//getNameFunc是作object的方法调用,this = object;
var second = first();//运行环境是全局,first作为匿名函数调用,是window对象的方法,所以this = window
second();//
为什么匿名函数没有取得其包含作用域(外部作用域)的this对象呢? 每个函数被调用时,其活动对象都会自动取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。 《Javascript高级程序设计》
怎么把结果输出object对象的name呢?
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this; //this = object;
return function(){
console.log(this.name+'哈哈哈哈哈');//this = window;
return that.name;
};
}
};
alert(object.getNameFunc()());//My Object
//这里,object对象作为变量对象被外部的函数访问,结果为my object;
//!!!!!但是,this.name 还是The window;解释和上面一个例子一样;