关于JavaScript匿名函数与闭包的一些解释
JavaScript作为一种非常奇特的动态脚本语言,具有一些特有的语法特性,其中匿名函数和闭包特性可以说很大程度上区别了JavaScript程序设计与其他传统语言程序设计的方法。
匿名函数:
var x = function() { document.write('hello world!'); }; x();
上面这个例子是一个最简单的匿名函数,显而易见的事实有三点:第一,函数没有被命名;第二,函数以对象的形式赋值给变量x;第三,我们也可以通过变量名x来调用这个函数。这使得函数能够非常方便地以参数的形式进行传递。
闭包:
关于闭包特性有许多复杂的解释,但是为了便于理解,简单来说就是,一个变量的作用域或者生命期,与其所在的源代码中的位置有关,而不是与运行时的上下文相关。下面是一个关于闭包的小例子(来自维基百科):
function derivative(f, dx) { return function (x) { return (f(x + dx) - f(x)) / dx; }; } var result = derivative(function(x) { return x * x; }, 0.000001)(5); document.write(result + '<br />');
上面的代码实际上是在求函数某一点上的近似的导数值。
derivative这个函数接受两个参数,f应该是接受一个数值型变量的函数,dx应该是一个很接近0的浮点数。然而derivative实际上并没有返回一个确切的导数值,因为并没有得到需要求解的确切的横坐标的值,因此返回了原函数f的导函数。请注意,有一个只接受一个参数x的匿名函数作为返回值被derivative函数返回了。
下面定义了result变量,首先调用derivative求导函数,需要传入两个参数,f传入了一个匿名函数x平方,dx按照要求传入一个很小的值0.000001(你也可以取得更大一些或更小一些)。接着应该就得到了一个导函数,再为导函数传入常量参数5,得到了x平方在x=5这一点上的近似导数值,输出的结果非常接近10,也是我们期待的结果。
接下来反过来看一看函数执行的实际过程。
- derivative函数被定义。
- derivative被调用,此时derivative函数得到的实参分别是f=function(x) {return x * x;}和dx=0.000001。
- 函数返回一个函数function (x) { return (f(x + dx) - f(x)) / dx; }。
- 随后调用这个刚刚被返回的函数,实参是x=5。请注意,按照传统语言的变量作用域,此时derivative函数应当早已退出堆栈,其参数f和dx的值应当早已不在内存,而在JavaScript中,此时f和dx的值却仍然保留为derivative函数被调用时的值,仅因为这个匿名函数被写在了derivative函数的内部。