`
rapheal
  • 浏览: 170885 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

我对Javascript闭包的一点点理解

阅读更多

前言

如果前端人员不懂Javascript闭包,那只能说他压根就没懂Javascript,只能算入门级。本篇主要是写本人对闭包的一些理解,欢迎拍板。

 

闭包概念

先引用一下官方解释:

 

A "closure " is an expression (typically a function) that can have free varuables together with an environment that binds those variables (that "closes" the expression)

 

用我的蹩脚英语翻译过来换成自己的理解就是:

 

1.闭包首先是一个表达式,通常这个表达式是一个函数。

2.闭包拥有一个环境,使得它能够拥有这个环境底下的这个许多变量。

 

闭包举例

可能上边解释还是有点抽象,那我拿实际的代码举个例子:

var name = "window";
			
function outer(){
	var name = 'outer';

	function inner(){
		return name;
	}

  return inner;
}

alert(outer()()); 

 

可以试着在浏览器运行一下这段script,会发现,弹出框内容为outer。

我先解释这个过程大致发生了什么,再联系前面说的两点说说我对闭包的理解。

首先第一行定义了name变量,很容易理解,name就是属于当前的浏览的页面吧!(实际name就是在当前window底下的全局变量,至于window是什么变量,不懂的话就把它当做是当前页面所在的环境吧)。

第2行-第12行我们定义了outer函数。

再看看第13行发生了什么,outer()()这是什么语法???那我们先分解来看吧,outer()一般是干嘛呢?当然是执行outer函数然后返回一个值咯。那在这里返回值是什么呢?inner!好,那就是说outer() == inner,应该同意吧?

于是乎outer()() == inner(),

所以最后alert出来的值将会是inner函数返回的值。

 

乱了乱了,不是说过,在一对括号{}里算是一个域,在这个域里边定义的东西,在离开这个域之后就会被销毁吗?

上面这个观点是对的,但是这个就是javascript闭包强大的地方:它把本来要销毁的一些变量给挽救回来,继续放在内存里边,让后边可以调用这个闭包来获取这些变量。

 

回到例子上吧,我们在outer函数里边定义了inner函数,如果说你最后不把它返回并且复制给变量,这个inner函数就会被销毁了,但是我们在第13行将它抛出去给外界执行了!!!于是js解释器知道它被暴露在外头了,不应该被销毁,所以就留住它的所在的环境,也就是outer的这个域。里边的name也被留下来了。

 

执行outer()之后,我们获取了刚刚说被暴露在外边的inner函数了,紧接着执行inner(),于是inner就开始找寻name变量了,我们知道inner所在的环境被嵌套了2层,inner->outer->window,当然啦,按照我们就近原则,我们肯定现在inner里边找name变量,发现找不到,于是到outer那个环境去找,此时找到了name,把name返回给inner()调用处alert出来。(这里可以思考一下脚本找寻变量的过程,就可以知道过多地访问全局变量会经常要把时间消耗在搜索过程,所以尽量避免过多地访问全局变量,至于怎么做,比较简单的就是采用一个局部变量记录该全局变量并替换成访问该局部变量)

 

例子跟概念的联系

我简单的把上述例子跟前面的解释联系起来:

1. 闭包首先是一个表达式,通常这个表达式是一个函数。

    例子中的inner函数就是这么一个表达式。

2. 闭包拥有一个环境,使得它能够拥有这个环境底下的这个许多变量。

    inner函数返回并提供给外界调用导致了inner会继续停留在内存,从而提供了一个环境可以访问outer里边的变量。

 

我的理解

按我理解,可以把闭包以及闭包的用法简单总结成以下:

1.闭包一般就是函数,并且定义在一个函数里边的。当然了,闭包还可以是一个对象的。如下代码:

function outer(){
	var name = 'outer';

	return {
		inner:function(){
			return name;
		}
	};

}

alert(outer().inner());

2.在函数里边定义函数不一定是闭包,而是应该将这个函数返回并且赋值给外界或者给外界执行这个闭包。

因为js解释器要知道到底要不要销毁域底下的东西,如果它发现外界持有这个闭包的引用,它就不会去销毁这个环境。

3.闭包允许外界访问函数里边的局部变量,例如outer里边的name变量。

4.运用闭包可以储存函数里边的变量,可以避免更多的全局变量定义而污染,我觉得可以简单的跟面向对象的封装进行类比。

5.闭包会导致变量跟一些引用停留在内存不被销毁,将会导致内存消耗。

 

本篇总结

对于Javascript,我认为它的闭包是其精华所在,使它变得更加灵活以及衍生了很多高级功能。关于闭包,网上有很多精彩的讲解,这里只是记录一下本人的理解,欢迎交流。阮一峰的学习Javascript闭包(Closure) 对闭包的讲解很不错,推荐阅读一下。

1
5
分享到:
评论

相关推荐

    当javaScript从入门到提高前需要注意的细节:闭包部分

    不过jQuery很好的证明了闭包非常好用,C#的Linq也证明的闭包技术的重要性,所以花一点点时间来理解下闭包还是很值得的,再说了,以下的内容不过就是一杯茶的时间而已。先给出一个闭包的定义:在计算机科学中,闭包...

    Javascript权威指南(第六版中+英文版)+源代码.zip

    JavaScript,作为全球最广泛使用的编程语言之一,是创建交互式网页和动态应用的关键工具。《JavaScript权威指南》第六版是广大开发者深入理解这门语言的重要参考资料。这本书包含了中英文两个版本,以及配套的源代码...

    javascript_snippets:一点点JavaScript编码练习和摘要

    JavaScript有强大的对象系统,对象是一组键值对的集合,可以视为关联数组。通过字面量语法`{key: value}`或构造函数创建对象。原型链是JavaScript继承的基础,通过`__proto__`属性或`Object.getPrototypeOf`方法访问...

    javascript-jogging:Javascript 的每日提交

    "javascript-jogging"项目似乎旨在通过每天的练习和提交来帮助用户提升JavaScript技能,就像慢跑一样,每天坚持一点点,逐渐增强编程能力。 在JavaScript的学习过程中,以下几个关键知识点是不可或缺的: 1. **...

    javascript-challenge:javascript专案

    参与这样一个项目不仅有助于提升JavaScript编程技巧,还能增强解决问题的能力,同时对Web开发的整体流程有更深入的理解。通过解决挑战,开发者可以更好地准备应对实际工作中的问题,并为未来的项目积累宝贵经验。

    前端面试每日31以面试题来驱动学习提倡每日学习每天进步一点

    这个项目提倡的是持续学习的理念,强调每天的进步,哪怕只是一点点,都能在长期积累后带来显著的成长。 JavaScript作为前端开发的核心语言,其知识点涵盖了变量、数据类型、控制结构、函数、对象、闭包、原型链、...

    Javascript

    总的来说,JavaScript的学习涵盖了从基础语法到高级特性的广泛内容,结合SCSS可以提升样式编写体验,而深入理解并实践项目结构将帮助你成为一名全面的Web开发者。无论你是初学者还是经验丰富的开发者,持续学习和...

    Javasript-Journey:javascript学习日记

    这个名为“Javasript-Journey”的项目,是一份详尽的JavaScript学习日记,旨在帮助开发者记录并理解JavaScript的核心概念和技术。 首先,JavaScript是一种解释型的、基于原型的、动态类型的脚本语言。它最初被设计...

    notes-codefellows-js-dev:我的代码研究员JavaScript开发加速器的笔记

    【标题】"我的代码研究员JavaScript开发加速器的笔记"提供了对一个特定的编程教育课程——JavaScript开发加速器的深入学习记录。这个课程可能是由Code Fellows提供的,它是一家知名的编程教育机构,专注于培养软件...

    JavaScript使用过程中需要注意的地方和一些基本语法

    理解并熟练运用这些JavaScript的基本语法和特性,可以帮助开发者编写出更高效、更易于维护的代码。同时,随着JavaScript的不断演进,学习新的特性和最佳实践也是至关重要的。例如,ES6引入的类、箭头函数、模板字符...

    web-231:学习JavaScript语言的基本概念

    此外,我们还会涉及JavaScript的作用域和闭包,这是理解变量可见性和内存管理的关键。全局变量在整个脚本中都可访问,而局部变量仅在其声明的函数内部可用。闭包则是一种特殊现象,它可以访问并操作函数内部的变量,...

    Currying:用Javascript编写

    Currying在JavaScript中不仅是一种技巧,也是一种设计模式,它能帮助我们写出更加模块化和易于理解的代码。通过利用Currying,开发者可以创建出更加灵活的函数,同时提高代码的复用性。在实际开发中,尤其是函数式...

    [removed]基本JavaScript示例

    6. 对象(Objects):JavaScript的对象是键值对的集合,可以看作是一个无序的“字典”。对象可以通过花括号 `{}` 创建,属性通过点`.`或方括号`[]`访问。例如: ```javascript let person = { firstName: "John",...

    Eloquent:雄辩的Java脚本练习

    这份练习资料可能是通过一系列的实例和挑战,引导读者掌握JavaScript的核心概念,如变量、数据类型、控制流、函数、对象、数组、闭包、原型链以及异步编程等。 1. 变量与数据类型:JavaScript是一种动态类型语言,...

    JavaScript-30

    "JavaScript-30" 是一个在线课程或项目挑战的名称,旨在通过30天的实践练习,帮助开发者提升他们的JavaScript技能。这个项目通常包括一系列小的JavaScript编程任务,覆盖了前端开发中的各种核心技术,比如DOM操作、...

    考试类精品--️每天花5分钟的时间,弄懂一道面试题 or Js小知识 来鞭策自己学习思考,每天进步一点,流年笑掷,未.zip

    "每天花5分钟的时间,弄懂一道面试题 or Js小知识"揭示了这份资源的目的,即通过每日的学习和思考,帮助用户逐步提升技能,每天进步一点点。"流年笑掷,未来可期"可能是这个学习计划的口号,鼓励持续努力,期待未来...

    Everything-in-[removed]JavaScript中的所有内容

    - 对象:JavaScript中的对象是一组键值对,可以通过字面量语法或构造函数创建。 - 原型与原型链:JavaScript对象有一个隐藏的prototype属性,通过它可以访问到原型对象,形成原型链,实现继承。 - 构造函数与实例...

    mandatory-web-shop:JavaScript课程中的4个作业(在自己的分支中)

    这个项目可能是某个在线课程的一部分,其中包含了四个JavaScript作业,学生需要在自己的分支中完成。Alesja是这个项目的提交者,可能是一位参与学习的学生或者是导师。 JavaScript是一种广泛使用的、基于浏览器的...

    Blog

    2. **函数和闭包**:深入理解函数,包括函数表达式、作用域、回调函数以及闭包的概念,是JavaScript进阶的关键。闭包允许函数访问并操作其外部作用域的变量,即使在其父函数已经执行完毕后。 3. **原型和原型链**:...

    assignment04

    【描述】由于描述只给出了“assignment04”这一信息,我们可以推测这可能是一个系列作业中的第四部分,旨在深化学生对JavaScript的理解和实践能力。通常,这样的作业会逐步递增难度,涵盖更多的概念和技术。 【标签...

Global site tag (gtag.js) - Google Analytics