【JS】JavaScript中的闭包

  在JavaScript中,闭包指的是有权访问另一个函数作用域中的变量的函数;创建闭包最常见的方式就是在一个函数内创建另一个函数。如下例子:

function A(propertyName){
    return function(object1, object2){
        var v1 = object1[propertyName];  
        var v2 = object2[propertyName];
        ...
    }
}

  

上面的例子中返回了一个内部函数(一个匿名函数),第3、4行代码之所以能访问外部函数中的变量propertyName,是因为内部函数作用域链中包含A()的作用域。

       理解函数的第一次被调用:当某个函数第一次被调用时,会创建一个作用域链(其实在函数创建时就存在)及一个执行环境,并把作用域链值赋给内部属性[[Scope]],再使用this、arguments和其他命名参数的值来初始化函数的活动对象。在作用域链中,外部函数的活动对象始终处于第二位,......直至全局执行环境。如下例子:

function sum(v1, v2){
    if(...){
        return -1;    
    }else if(...){
        return 1;    
    }else{
        return 0;    
    }
}
var result = sum(1, 2);

  

上面的例子中,定义了sum()函数,再在全局作用域中调用它,第一次调用sum()时,会创建一个包含this、arguments、v1、v2的活动对象,全局执行环境的变量对象(this、result、sum)在sum()执行环境的作用域链中处于第二位。

 

这里要注意的是,当函数执行完后,其活动对象也还没被销毁,如在第一个例子A()中,因为匿名函数的作用域链仍然引用着活动对象,直到匿名函数被销毁,A()的活动对象才会被销毁。如:

var a = A('name');  // 创建函数
// ...调用函数
a = null;  // 解除对匿名函数的引用,释放内存

  

通过将a设为等于null,解除了该函数的引用,垃圾回收例程会将其回收,匿名函数的作用域链也将被销毁。

 

关于this:

看下面例子:

var name = "aa";

var obj = {
	name : "bb",
	getName : function(){
		return function(){
			return this.name;
		};
        }
};

alert(obj.getName()());  // "aa"

  这里返回的name值是全局作用域下的,匿名函数并没有取得其外部作用域的this对象。因为每个函数在被调用时,其活动对象都全自动取得两个特殊变量:this和arguments,内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此在这个例子中不会访问到外部函数的这两个变量。如果将外部作用域中的this对象保存在一个闭包能访问到的变量里,就可以让闭包访问到该对象。如下:

var name = "aa";

var obj = {
	name : "bb",
	getName : function(){
	        var that = this;
		return function(){
			return that.name;
		};
        }
};

alert(obj.getName()());  // "bb"

  

 

 

if ("你对我感兴趣") {

return  "点击到简书找我玩";

}

else{ 

 return "带着受伤的心谢谢您~";

}

 

posted @ 2017-03-08 23:46  吉古力  阅读(280)  评论(0编辑  收藏  举报