文档章节

闭包与node.js

花果山妖
 花果山妖
发布于 2014/08/21 10:39
字数 1272
阅读 274
收藏 3

私人博客文章地址:http://121.40.121.153/2014/08/20/bi-bao-yu-node-js/ 今天在看《Professional Node.js》的时候提到了闭包,说闭包的机制可以帮助事件驱动的编程模式( event-driven programming)的实现。

为了弄清楚闭包的概念翻看了各种各样的文档。下面总结一下个人的理解,此文章不一定权威,但也不会瞎说的,囧~ ##什么是闭包,先别急

闭包的概念被各种人定义的神乎其神,看了之后不懂是常态。其实理解闭包的概念还是应该从需求说起,这样比较好理解。

首先,我们必须知道,闭包并不是js得专利,这一概念也不是从js中创造出来的,今天的大部分高级语言(Python、Ruby、Lua等)都支持闭包这一特性。那么闭包究竟是什么,别急,让我慢慢道来,在这里我可以先说明一点:闭包是为了给现今的高级语言增加灵活性所催生出的产物。虽然我只是感觉,但我觉得闭包这个东西的出现有点“迫不得已”的意味,为什么这么说呢,因为在js这类脚本语言当中增加了很多传统语言没有的东西,比如作用域链、把函数作为“第一类对象”(first-class object)等特性,而为了维持这些特性,就必须引入闭包机制。 ##传统的函数调用方式

我们先看看传统的函数是怎么工作的。

函数内部的代码与外界的联系仅限于传参机制和返回值机制。说的更底层一些,每个函数在调用时在内存中用独立的栈储存,调用完成之后,回收所用栈的内存。这过程中的输入输出就是传参和return。而函数内部所用到的变量全部是局部变量,在函数直接完成之后就释放了,和整个程序没有太大关系。 ##javascript的高级特性

而在js中,有了两个明显的特性,改变了上面所说的比较简单的函数执行方式。

第一个是作用域链的概念。传统的函数内部的作用域只有函数内部本身和传入的参数。而在js中,作用域向上扩展。内部函数可以看到并利用其母函数中的变量和全局变量。并且可以直接在函数内部使用它们。这就造成了子函数与母函数的耦合特性。当你调用一个子函数时,其母函数中所用到的部分也必须被调用。而这个被调用的整体(并非只有子函数本身)就被称作一个闭包。

第二个是把函数作为“第一类对象”(first-class object)。函数在js中可以被赋予给一个变量,可以被当做一个参数传给另一个函数,还可以作为一个函数的返回值。这都得益于其函数在语言中作为“第一类对象”。这就使函数的嵌套成为常态。函数可以被当做变量任意传递、返回。这就使函数的必须明确自己的作用域。当被变量引用到其他位置是,还是要绑定它自己原有的作用域。而这个被作用域捆绑到一起的代码集合就是闭包。 ##举个栗子

通过上面的两点,也许你对闭包已经有了一定了解,其实想更深入的弄清楚闭包,重要的是弄清楚函数运行的机制。

好吧,下面我们举个例子:

当一个子函数引用一个母函数中的变量,且又将这个子函数作为母函数的返回值返回(有点绕,都读两边,囧~)。具体参照下面代码。

function f1()
	var n=999;
    function f2(){
    	alert(n); 
    }
    return f2;
}
var result=f1();
result(); // 999

当你最后调用 result()时,其实就产生了闭包。result引用的其实是f2;因为f2作为了f1的返回值。而f2中有调用了f1中的n,所以,在返回时,n也要连带的被返回出来。其实用起来合情合理。没神马异常的地方。 ##闭包与node.js

node.js用的是事件驱动型编程或者叫一步编程。所有的任务由事件触发,这就要在事件函数中大量遇到回调函数(call back),而回到函数基本上都会触发闭包机制,也就是调用函数外部的变量。而有了闭包机制,这些事情全部不需要编程者操心,而是由语言本身帮你完成。最后引用《Professional Node.js》中的话

This shows that by using the closure pattern, you can have the best of both worlds: You can do event-driven programming without having to maintain the state by passing it around to functions. A JavaScript closure keeps the state for you.

好啦,今天就写到这!明天讲讲node.js的事件驱动机制(event-driven)。

© 著作权归作者所有

共有 人打赏支持
花果山妖
粉丝 3
博文 17
码字总数 9727
作品 0
沈阳
私信 提问
如何封装Node.js和前端通用的模块

前端模块通常是我们开发人员为了避免和他人冲突才把模块代码放置在一个闭包中。 如何封装Node.js和前端通用的模块,我们可以参考Underscore.js 实现,他就是一个Node.js和前端通用的功能函数...

cd_ing
2014/02/17
0
0
node.js的模块化及reqire与exports释义

模块引入 模块化是node.js的核心概念,node.js对于服务端的操作都是封装成一个个独立的核心模块,以文件读写模块为例: 执行结果: require node.js是经由关键字引入模块,模块分为:自带的核...

章鱼喵_
2018/07/10
0
0
Node.js中实现文件的循环写入

http://developer.51cto.com/art/201109/290289.htm node.js对所有外部资源调用提供异步机制,文件IO也不例外。在这种异步机制下,进程不会被阻塞,这极大提高了CPU的利用率,为单进程的模式...

壹峰
2018/04/17
0
0
深入浅出Node.js(一):什么是Node.js

专栏的第一篇文章《什么是Node.js》尝试从各个角度来阐述Node.js的基本概念、发展历史、优势等,对该领域不熟悉的开发人员可以通过本文了解Node.js的一些基础知识。 从名字说起 有关Node.js...

leeldy
2012/10/25
0
1
初识 SeaJS

最近NodeJS和CommonJS真是好火啊,前端真的不再如从前那么“单纯”了,从此需要学习掌握更多的传统软件开发的知识和技能,也就是从前后端开发做的很多工作会逐渐前移到前端工程师。这里为什么...

Sephiroth
2012/03/12
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

winscp中使用sudo的方法

用截图了解如何在 WinSCP 中使用 sudo。 首先你需要检查你尝试使用 WinSCP 连接的 sftp 服务器的二进制文件的位置。 你可以使用以下命令检查 SFTP 服务器二进制文件位置: [root@kerneltalk...

Linux就该这么学
17分钟前
0
0
四、MyBatis中查询执行流程

一、查询执行大致流程 在MyBatis中,查询执行的大致流程如下:

yangjianzhou
23分钟前
0
0
系统幂等设计

前言 幂等简单的定义: 系统中的多次操作,不管多少次,都应该产生一样的效果,或返回一样的效果。 比如实际的业务请求为创建一个活动,理论上需要根据业务形态开发幂等创建活动的接口,这样...

春哥大魔王的博客
48分钟前
2
0
DevSecOps 运维模式中的安全性

导读 本文想从技术的角度谈谈我对云计算数据中心 DevSecOps 运维模式中的安全性的理解,和过去几年我在云服务业务连续性管理方面的探索。 现在公有云服务商都不约而同地转向 DevSecOps 模式。...

问题终结者
50分钟前
0
0
java 基础脑图 转载来的

NotFound403
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部