文档章节

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

指尖残雪
 指尖残雪
发布于 2016/05/22 23:57
字数 848
阅读 11
收藏 0
点赞 2
评论 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变量。






© 著作权归作者所有

共有 人打赏支持
指尖残雪
粉丝 7
博文 73
码字总数 0
作品 0
上海
后端工程师
【译】【nodeschool】【scope-chains-closures】作用域

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

小草先森 ⋅ 05/14 ⋅ 0

【前端工程师手册】JavaScript作用域拾遗

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

推荐码发放 ⋅ 05/17 ⋅ 0

搞明白JavaScript中的匿名函数

匿名函数顾名思义指的是没有名字的函数,在实际开发中使用的频率非常高!也是学好JS的重点。 匿名函数:没有实际名字的函数。 首先我们声明一个普通函数: 然后将函数的名字去掉即是匿名函数...

张培跃 ⋅ 06/09 ⋅ 0

深入理解闭包之前置知识→作用域与词法作用域

前言 这两天刚好和朋友讨论到闭包,这个JavaScript中的“神兽”,很多同学会觉得闭包这玩意太闹心了,怎么着都理解不了...其实刚接触JavaScript的时候我也是这样的。 但是呢,闭包却非常重要...

lce_shou ⋅ 05/16 ⋅ 0

深入理解闭包之前置知识---作用域与词法作用域

前言 这两天刚好和朋友讨论到闭包,这个JavaScript中的“神兽”,很多同学会觉得闭包这玩意太闹心了,怎么着都理解不了...其实刚接触JavaScript的时候我也是这样的。 但是呢,闭包却非常重要...

iceman_dev ⋅ 05/15 ⋅ 0

JavaScript核心概念归纳整理

原文出处: 熊俊漉 JavaScript语言本身是一个庞大而复杂的知识体系,复杂程度不低于任何一门后端语言,本文针对JavaScript语言的核心概念进行简单的梳理,对应的每个知识点仅仅点到为止,不作...

音乐宇Code ⋅ 05/27 ⋅ 0

探索JavaScript函数式编程的来龙去脉

阿里巴巴前端工程师逸翾对JavaScript中的函数进行了详细讲解。首先谈及了环境作用域,其中说明了块级作用域和作用域链,接着解释了闭包的作用,最后重点分析了JavaScript的函数式编程,包括纯...

云迹九州 ⋅ 04/28 ⋅ 0

前端基础(二):变量声明的6种方法

字数:2869 阅读时间:10分钟 最新的ECMAScript规范中,变量声明有var、function、let、const、import、class六种方法。 var 语法: var varname [= value1 [, vaname1[,valname2 ...]]]; 对...

老司机带你撸代码 ⋅ 06/09 ⋅ 0

这一次,我们换种姿势学习 javascript

前言 《你不知道的 javascript》是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途。本书介绍了该系列的两个主题:“作用...

程序员解决师 ⋅ 05/29 ⋅ 0

【前端工程师手册】JavaScript之作用域

【前端工程师手册】JavaScript之作用域 什么是作用域 来一段《你不知道的JavaScript-上卷》中的原话: 几乎所有编程语言最基本的功能之一,就是能够储存变量当中的值,并且能在之后对这个 值...

优惠券活动 ⋅ 05/17 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

马氏距离与欧氏距离

马氏距离 马氏距离也可以定义为两个服从同一分布并且其协方差矩阵为Σ的随机变量之间的差异程度。 如果协方差矩阵为单位矩阵,那么马氏距离就简化为欧氏距离,如果协方差矩阵为对角阵,则其也...

漫步当下 ⋅ 昨天 ⋅ 0

聊聊spring cloud的RequestRateLimiterGatewayFilter

序 本文主要研究一下spring cloud的RequestRateLimiterGatewayFilter GatewayAutoConfiguration @Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMi......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部