一、相关概念
1、动态程序设计语言(Dynamic Programming Language )
Dynamic Programming Language (动态语言或动态编程语言) 动态语言,准确地说,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化。比如众所周知的ECMAScript(JavaScript)便是一个动态语言。除此之外如Ruby、Python等也都属于动态语言,而C、C++等语言则不属于动态语言。
2、 动态类型语言和静态类型语言
动态类型语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。Python和Ruby就是一种典型的动态类型语言,其他的各种脚本语言如VBScript也多少属于动态类型语言。
静态类型语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语言的典型代表,其他的静态类型语言还有C#、JAVA等。
3、 函数式编程( 参考)
二、闭包
闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。在下面的函数中print函数就是一个闭包
function randomAlert(){ var x=Math.random(); function print() {console.log("产生的随机数",x); } return print;}var a=randomAlert();var b=randomAlert();a();b();
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,
另一个就是让这些变量的值始终保持在内存中。function f1(){ var n=999; nAdd=function(){n+=1}//nAdd全局变量 function f2(){ console.log(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000
在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中, 而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后, 被垃圾回收机制(garbage collection)回收。 这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行, 首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量, 而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function), 而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter, 可以在函数外部对函数内部的局部变量进行操作。