文档章节

javascript之块级作用域的概念和闭包

指尖残雪
 指尖残雪
发布于 2016/05/22 23:57
字数 848
阅读 13
收藏 0

简单的块级作用域:

javascript没有块级作用域的概念

function test(){                          
	for(var i = 1 ; i <=5; i++){  //i     
		alert(i);                         
	}                                     
	alert(i);  //6                        
}                                         
                                          
test();
最后会输出6.
只有当test执行完毕后I才会被垃圾收回机制收回。

为了避免这种情况发生,可以把里面的for循环作为一个单独的域。使用function包含起来。

function test(){                             
	function(){                             
		for(var i = 1 ; i <=5; i++){  //i    
			alert(i);                        
		}						             
	};                                    
	alert(i);                                
}

但是function不会自己执行,在js中()表示执行

function test(){                              
	(function(){                              
		for(var i = 1 ; i <=5; i++){  //i     
			alert(i);                         
		}						              
	})();                                     
	alert(i);                                 
}                                             
test();
这样就不会把6输出。

把一个函数直接使用(function(){...})()形式可以直接执行。

(function(){alert('我直接执行了!');})();

闭包

在程序语言中,所谓闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型变量神奇地保留他们在闭包最初定义(或创建)时的值

上面的解释不用完全理解(我刚刚看到也懵了),下面直接看代码:
var name = "xiao A";                    
var obj = {                             
      name : "xiao B" ,                 
      getName: function(){              
		return function(){              
			return this.name;           
		}                               
	}                                   
};                                      
alert(obj.getName()());
结果不是输出“xiao B”,而是“xiao A”
原因:
当我们alert(obj.getName());时,返回结果为:
function(){
return this.name;
}

这个时候使用obj.getName()(),作用于已经是在window中了,在obj的外层。返回“xiao A”相当于如下代码:

var name = "xiao A";                    
var obj = {                             
      name : "xiao B" ,                 
      getName: function(){              
		return function(){              
			return this.name;           
		}                               
	}                                   
};                                      
                                        
alert(obj.getName()());			        
var k = obj.getName();  //全局作用域         
//alert(typeof k); // function类型        
alert(k());
结果一样输出“xiao A”

如果想要输出“xiao B”,需要一个变量保存当前的调用者的对象。

var name = "xiao A";                
var obj = {                         
      name : "xiao B" ,             
      getName: function(){          
	  	// this总是指向调用者              
		var o = this;               
		                            
		return function(){          
			return o.name;          
		}                           
	}                               
};                                  
//alert(obj.getName()());	        
                                    
var k = obj.getName();              
alert(k());
用o保存obj的this对象,总是指向调用者,getName()的调用者是obj,所以o就代表obj,返回的就是o.name


闭包说简单些:闭包:一个函数 可以访问另外一个函数作用域中的变量

闭包示例:

function f(x){		// 假设为 2级作用域                                                   
			var temp = x ; 		//局部变量	 //temp已经没有被使用	                   
			return function(x){		// 3级作用域  (function 有了一个执行域 var obj)        
				temp += x ;		//  又被使用了						           
				alert(temp);						                       
		     }                                                             
}				                                                           
var a = f(50);                                                             
//alert(a);                                                                
                                                                           
a(5);				                                                       
a(10);                                                                     
a(20);
当我调用f(50)的时候temp=50,返回function(x){temp+=x;alert(temp);}并赋给a。然后再执行a(5),输出55。再执行a(10),输出65。再执行a(20),输出85。

当我return赋值给a后作用域和f(x)的作用域是一样的,按照一般说法就不能访问f里面的temp变量,temp变量会被垃圾回收机制收回,但不是这样,当垃圾回收机制检测到temp使用过后会继续检查return的函数,发现函数里面继续使用temp,会再次标记temp被使用。

当调用a(5)时候,检测到后面还调用a函数,用到temp变量,所以temp变量会再次被标记不会被回收。

简单的理解就是:这样我们就相当于在一个a函数中访问f函数中的temp变量。






本文转载自:http://blog.csdn.net/bq1073100909/article/details/48706145

共有 人打赏支持
指尖残雪
粉丝 7
博文 73
码字总数 0
作品 0
上海
后端工程师
原生javascript学习:javascript闭包实例

之前看zakas的Professional JavaScript,读过闭包的章节,当时觉得理论上是理解了,把书上的案例都实践了一遍。但例子是纯粹控制台调试实现的,印象不深刻,今天练习原生javascript的时候碰上...

黎宇浩
2012/06/15
0
0
你不知道的JavaScript·第一部分

第一章: 作用域是什么 1、 编译原理 JavaScript 被列为 ‘动态’ 或 ‘解释执行’ 语言,于其他传统语言(如 java)不同的是,JavaScript是边编译边执行的。 一段源码在执行前会经历三个步骤...

曾田生z
06/25
0
0
【译】【nodeschool】【scope-chains-closures】作用域

作用域链与闭包工作 作用域,作用域链,闭包以及垃圾回收它们有一个共同点:那就是它们通常都是手动执行的。闭包实际上是如何工作的?垃圾回收在什么时候发生?作用域链到底是什么? 通过这次...

小草先森
05/14
0
0
【前端工程师手册】JavaScript作用域拾遗

【前端工程师手册】JavaScript作用域拾遗 昨天总结了一些作用域的知识【前端工程师手册】JavaScript之作用域,但是发表完发现忘记了一些东西,今天拾个遗。 昨天说到了JavaScript中没有块级作...

推荐码发放
05/17
0
0
web前端学习:深入理解JS闭包

第一部分:初遇闭包 http://www.runoob.com/js/js-function-closures.html 什么是闭包?闭包有什么作用?这是我遇到闭包时的第一反应。 闭包在JavaScript高级程序设计(第3版)中是这样描述:...

IT智云编程
07/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

原型模式

1、原型模式-定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 克隆(浅度克隆->拷贝值类型或者引用,深度克隆->创建新的对象,开辟新的内存) 例如客户端知道抽象Pro...

阿元
今天
40
0
awk命令扩展使用操作

awk 中使用外部shell变量 示例1 [root@centos01 t1022]# A=888[root@centos01 t1022]# echo "" | awk -v GET_A=$A '{print GET_A}'888[root@centos01 t1022]# echo "aaaaaaaaaaaaa" | aw......

野雪球
今天
33
0
深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
今天
43
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
今天
33
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
43
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部