JavaScript闭包深入解析
for (var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
——上面这段代码,如果对JavaScript闭包没有概念的话,将是一头雾水。 by 羊大葱 于2016年10月25日
几种典型闭包写法
1、最基础写法
function foo() {
var a = 2;
function bar() {
console.log( a );
}
return bar;
}
var baz = foo();
baz(); // 2 —— 麻麻快看,这就是闭包的效果。
2、较为变种写法
function foo() {
var a = 2;
function baz() {
console.log( a ); //
}
bar( baz );
}
function bar(fn) {
fn(); // 妈妈快看呀,这就是闭包!
}
2.1第二种写法简明写法(传递函数间接的传递)
var fn;
function foo() {
var a = 2;
function baz() {
console.log( a );
}
fn = baz; // 将baz 分配给全局变量
}
function bar() {
fn(); // 妈妈快看呀,这就是闭包!
}
3.直接外面函数引用
function wait(message) {
setTimeout( function timer() {
console.log( message );
}, 1000 );
}
wait( "Hello, closure!" );
将一个内部函数(名为timer)传递给setTimeout(..)。timer 具有涵盖wait(..) 作用域的闭包,因此还保有对变量message 的引用。wait(..) 执行1000 毫秒后,它的内部作用域并不会消失,timer 函数依然保有wait(..)作用域的闭包。
3.1 直接外面函数引用常见用法
function setupBot(name, selector) {
$( selector ).click( function activator() {
console.log( "Activating: " + name );
} );
}
setupBot( "Closure Bot 1", "#bot_1" );
setupBot( "Closure Bot 2", "#bot_2" );
如果你很熟悉jQuery(或者其他能说明这个问题的JavaScript 框架),可以思考3.1的代码。
本质上无论何时何地,如果将函数(访问它们各自的词法作用域)当作第一级的值类型并到处传递,你就会看到闭包在这些函数中的应用。在定时器、事件监听器、Ajax 请求、跨窗口通信、Web Workers 或者任何其他的异步(或者同步)任务中,只要使用了回调函数,实际上就是在使用闭包!
回到文章一开始的代码
为什么一直输出的是6呢?
由于很多开发者对闭包的概念认识得并不是很清楚,因此当循环内部包含函数定义时,代码格式检查器经常发出警告!
第一、在循环外部函数定义
function t1(a){console.log(a);};
for(var i=1; i<=5; i++){
setTimeout(t1(i),i*1000);
}
//----------------------------------------------------------
第二、直接在循环内部包含函数定义
for (var i=1; i<=5; i++) {
setTimeout( function timer() { console.log( i ); }, i*1000 );
}
上面两种写法,第一种输出时1、2、3、4、5;第二种写法输入为6,6,6,6,6。

上图是我在两种情况下,当迭代循环到5的时候打出‘d5’,以探究两种情况的执行顺序。很显然,第一种形成闭包情况下,是等迭代全部执行完才开始执行setTimeout();而第二种非闭包情况下是直接每个循环执行的!
JavaScript闭包深入解析的更多相关文章
- Javascript闭包深入解析及实现方法
1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点:1. 作为一个函数变量的一个引用,当函数返回时 ...
- JavaScript闭包底层解析
1. 闭包是一个函数,这个函数有权访问另一个函数作用域中的变量,创建闭包最常见的方式,就是在函数内部创建函数.要想彻底搞清其中细节,必须从函数从创建到调用的时候都发生了什么入手 2. 函数第一次被调用 ...
- JavaScript闭包(Closure)
JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...
- javascript闭包和作用域链
最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...
- Javascript闭包的一些研究
原文:Javascript闭包的一些研究 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助. 程序1 var f = (function( ...
- javascript闭包学习
(function(){})()===>>>>函数会被立即执行function(){}是一个函数用括号包起来表示是函数表达式再加()表示函数自执行 如何理解闭包?1.定义和用 ...
- javascript闭包—围观大神如何解释闭包
闭包的概念已经出来很长时间了,网上资源一大把,本着拿来主意的方法来看看. 这一篇文章 学习Javascript闭包(Closure) 是大神阮一峰的博文,作者循序渐进,讲的很透彻.下面一一剖析. 1. ...
- JavaScript闭包其一:闭包概论 函数式编程中一些基本定义
http://www.nowamagic.net/librarys/veda/detail/1707前面介绍了作用域链和变量对象,现在再讲闭包就容易理解了.闭包其实大家都已经谈烂了.尽管如此,这里还是 ...
- 【javascript闭包】转载一篇不错的解释,也有几个大牛的链接
初学闭包时一直以为很简单.但伴随对一个问题深入学习后,才算真正理解了闭包,同时也发现连<<JavaScript高级程序设计>>中都些不准确的地方. 我不准备从头介绍闭包的概念, ...
随机推荐
- TypeScript Generics(泛型)
软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用.支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性. 在C#和 ...
- 09 Object
Object 在看 ES6 Object的时候,我发觉ES5 Object 的更新我并不是完全知道. 于是觉得还是看一下. 1. __proto__ 作为一个 半吊子前端开发人员. 居然不知道这个.. ...
- jQuery中 pageX,clientX,offsetX,layerX的区别
一.PageX和clientXPageX和clientX ,这个两个比较容易搞混,PageX:鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化.可以理解为:相对#(0.0 ...
- win7电脑怎么修改计算机用户名Administrator
----------------------------------- 首先,在开始中打开我的控制面板.----->>打开用户账户和家庭安全选项.----->>,继续点击用户账 ...
- AE开发能否实现TOC Control里添加多个Data Frame
问题: 在ArcMap中,菜单Insert下Data Frame,可以在TOC中增加Data Frame,在MapControl或者PageLayoutControl下都可以正常显示多个Data Fr ...
- 深入理解javascript原型和闭包(4)——隐式原型
注意:本文不是javascript基础教程,如果你没有接触过原型的基本知识,应该先去了解一下,推荐看<javascript高级程序设计(第三版)>第6章:面向对象的程序设计. 上节已经提到 ...
- win7提示“User Profile Service服务未能登录”
注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 最近,有个同事打电话告诉我说他的用户名无法登陆到系统,提示“User Profile Service服务未能登录,无法加载用户配置文 ...
- Ruby常用比较操作符
操作符 含义 == 测试值是否相等 ==== 用来比较case语句的目标和每个when从句的项 <=> 通用比较操作符. 根据接受者小于, 等于, 大于其参数, 返回-1, 0. 1 & ...
- UI第十一节——UIActivityIndicatorView
- (void)viewDidLoad { [super viewDidLoad]; // 创建一个UIActivityIndicatorView,大小是固定的 UIActi ...
- 创建maven工程时总是带有后缀名Maven Webapp解决办法
做项目时突然遇到了一个新问题,从前没有的,今天不知怎么了突然有了这个问题,maven创建web项目时多出了后缀名maven webapp ,很碍眼,而且访问路径还得删了,这个后缀名才可访问,所以找了答 ...