深入理解JavaScript——闭包
跟很多新手一样我也是初入前端,对闭包的理解花费的时间和精力相当的多。效果也还行,今天我就来根据自己的理解细致的讲一讲闭包,由于是初入学习的时候不免有一些弯路和困惑,我想信这也是很多跟我一样的人会同样遇到的问题。我就以自己的学习路径和遇到的各种坑来谈闭包。希望对各位有一定的帮助。(菜鸟,也请各位多多指教)
闭包是什么?《JavaScript高级程序设计》上面这么描述的:闭包是指有权访问另一个函数作用域中的变量的函数。这句话第一次看的时候模模糊糊,似是而非。碰到问题就不会运用了,听别人的分析头头是道,说到底还是没搞明白。现在我觉得要彻底搞清这句话必须对JavaScript的作用域,匿名函数,甚至JavaScript的编译原理有一些简单的了解。经过查阅理解各种资料书籍对闭包的解释,再回过头来看了一些源码,慢慢的有了一点感觉。我觉得对闭包描述最好的一句话是:“闭包是基于词法作用域书写代码时所产生的自然结果,你甚至不需要为了利用它而有意为之的创建闭包,闭包的创建和使用是在你的代码中随处可见。你缺少的是根据你自己的意愿来识别,拥抱和影响闭包的思维环境。”话有点长但点出来闭包在JavaScript这么语言中存在的实际价值,大家可以细细体会一下。接下来我已实际例子来讲讲闭包。
首先看一个简单的例子:
function createComparisonFunction(propertyName){
return function(obj1,obj2){
var value1=object1[propertyName];
var value2=object2[propertyName];
if(value1<value2){
return -1;
}else if(value1>value2){
return 1;
}else{
return 0;
}
}
}
例子中返回的是一个匿名函数,其中匿名函数中value1,value2同时又对外部函数createComparisonFunction()的参数propertyName进行调用。再看看上面对闭包的定义:有权访问另一个函数作用域中的变量的函数。return的匿名函数有权访问外部函数作用域中的变量propertyName,因此这是一个闭包。但实际来说这只是一个基于词法作用域的查找规则,很好理解也很自然。
可能有些人不明白什么是词法作用域的查找规则:其实说简单点就是根据变量的作用链域来查找并取得该变量。以上例来说:createComparisonFunction函数的作用域包含一个变量property和一个匿名函数(由于没有函数名其实在createComparisonFunction函数中也无法调用,这也是匿名函数的一个缺点,记得事件监听函数调用一个匿名函数时是无法移除吗?道理是一样的),匿名函数作用域中包括obj1,obj2,value1,value2这四个变量。匿名函数中的变量调用时首先在自己作用域中查询,找到了该变量就调用,找不到就往外层走接着找,直到全局作用域如果还是找不到就会报ReferenceError(如果找到了一个var a;呢?由于a为undefined所以会报TypeError)。而createComparisonFunction函数则只能在他的作用域中查找,不能去内层的匿名函数中查找,这种查找规则就是词法作用域的查找规则(当然这不只是基本规则)。
我们再来看一个例子:
function foo() {
var a = 2;
function bar() {
console.log( a );
}
return bar;
}
var baz = foo();
baz(); //2
答案可能很多人都能猜出来但其实现原理是怎样呢?我现在就来细致的分析一下:首先声明了一个函数foo其作用域包括变量a和bar函数。foo函数内部有一个函数bar内部没有新变量。然后定义一个变量baz,其值为foo()而foo()返回bar,顾baz=bar;最后一句baz()即等价于bar();根据词法作用域的规则bar是在foo函数中声明的。外部是无法访问的呀!这正是闭包的神奇之处!我们再一次回到闭包定义:有权访问另一个函数作用域中的变量的函数,baz()函数有权访问foo函数中的bar。这就是闭包对吧!搞清闭包后有些人还会疑问?闭包是怎么形成的,为什么你说它有权访问foo中的bar呢?首先闭包的形成是在一个函数内部创建一个函数这是创建闭包的最常见方法。当将内部函数传递到它的词法作用域以外他都会持有对原始定义作用域的引用,执行此函数就会 使用闭包。
闭包的基础大概就是这几点,希望大家能仔细体会。抽时间补充点闭包的一些其他用途,来帮大家扩展一下思维。
深入理解JavaScript——闭包的更多相关文章
- 我从来不理解JavaScript闭包,直到有人这样向我解释它...
摘要: 理解JS闭包. 原文:我从来不理解JavaScript闭包,直到有人这样向我解释它... 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 正如标题所述,JavaScript闭包 ...
- 深入理解JavaScript闭包【译】
在<高级程序设计>中,对于闭包一直没有很好的解释,在stackoverflow上翻出了一篇很老的<JavaScript closure for dummies>(2016)~ ...
- 【转】深入理解JavaScript闭包闭包(closure) (closure)
一.什么是闭包?"官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述 ...
- 全面理解Javascript闭包和闭包的几种写法及用途
好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途. 一.什么 ...
- 深入理解JavaScript闭包(closure)
最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...
- 深入理解javascript闭包(一)
闭包(closure)是Javascript语言的一个难点.也是它的特色,非常多高级应用都要依靠闭包实现. 一.什么是闭包? 官方"的解释是:闭包是一个拥有很多变量和绑定了这些变量的环境的表 ...
- 深入理解javascript闭包(一)
原文转自脚本之家(http://www.jb51.net/article/24101.htm) 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- 深入理解Javascript闭包概念
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部能够直接读取全局变量 ...
- 轻松理解JavaScript闭包
摘要 闭包机制是JavaScript的重点和难点,本文希望能帮助大家轻松的学习闭包 一.什么是闭包? 闭包就是可以访问另一个函数作用域中变量的函数. 下面列举出常见的闭包实现方式,以例子讲解闭包概念 ...
- 【译】理解JavaScript闭包——新手指南
闭包是JavaScript中一个基本的概念,每个JavaScript开发者都应该知道和理解的.然而,很多新手JavaScript开发者对这个概念还是很困惑的. 正确理解闭包可以帮助你写出更好.更高效. ...
随机推荐
- [转]利用URLConnection来发送POST和GET请求
URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...
- kindeditor4整合SyntaxHighlighter,让代码亮起来
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换 ...
- 玩转spring boot——结合redis
一.准备工作 下载redis的windows版zip包:https://github.com/MSOpenTech/redis/releases 运行redis-server.exe程序 出现黑色窗口 ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- 分享两种实现Winform程序的多语言支持的解决方案
因公司业务需要,需要将原有的ERP系统加上支持繁体语言,但不能改变原有的编码方式,即:普通程序员感受不到编码有什么不同.经过我与几个同事的多番沟通,确定了以下两种方案: 方案一:在窗体基类中每次加载并 ...
- Js 数组返回去重后的数据
function removeRepeat(data) { var temp = ""; var mainData = []; for (var i = 0; i < dat ...
- 【从零开始学BPM,Day1】工作流管理平台架构学习
[课程主题] 主题:5天,一起从零开始学习BPM [课程形式] 1.为期5天的短任务学习 2.每天观看一个视频,视频学习时间自由安排. [第一天课程] Step 1 软件下载:H3 BPM10.0全开 ...
- 笔记:Memory Notification: Library Cache Object loaded into SGA
笔记:Memory Notification: Library Cache Object loaded into SGA在警告日志中发现一些这样的警告信息:Mon Nov 21 14:24:22 20 ...
- 工大助手(C#与python交互)
工大助手(爬虫--C#与python交互) 基本内容 工大助手(桌面版) 实现登陆.查成绩.计算加权平均分等功能 团队人员 13070046 孙宇辰 13070003 张帆 13070004 崔巍 1 ...
- 入园记------我的DBA之路
今天周一拖着疲惫的身躯 11点才离开公司,回到家估计写完这篇博客就要17号了. 一个人走在回家的路上,很黑,突然很多感触,一个人在北京拼搏,不敢停止学习的脚步,因为只要停下来就会感觉到孤独. 回顾一下 ...