WPTheme Java JavaScript…Yeah~!
Jun 24

  闭包

  我并没有刻意的去学习JavaScript,我必须快速上手。因为我觉得,我已经为这个现实的AJAX应用,在没有学习过JavaScript的情况下,做了充分的准备。一开始,我觉得我已经在程序员中下降了几个层次。(JavaScript!我的C++程序员朋友们会什么看呢?) 但当我平复了当初的反抗后,我开始意识到JavaScript其实是一个强大的,富有表现力和简洁的语言。JavaScript的特色,它可以自豪地说,那些其它的更流行的编程语言现在才刚刚开始支持。

  JavaScript的其中一个更高级的特性就是对闭包的支持,而C#2.0则是通过匿名函数来实现的。闭包是这样的一个运行时现象,一个内部函数(在C#叫匿名函数)可以访问它的外部函数的变量。很显然,这样做的意义不大,除非它的内部函数不知何故地可以访问外部函数的领域。让我们举个例子来讲清楚它。

  假设你想对一系列的数字进行过滤,只有大于100的数才能通过,而其它的就被滤掉了。你可以像Figure 8这样写一个函数。

  但现在,你又想写一个新的过滤标准,假设这次要求数值必须大于300,这样写:

var greaterThan300 = filter(
function(x) { return (x > 300) ? true : false; },
someRandomNumbers);

  接着,你又需要对大于50,25,10,600等的数值进行过滤。这下子,聪明的你不会不意识到,它们都有一个共同的谓语:”大于”,所不同的只是数值。因此,你可以这样写一个函数把数字列出来:

function makeGreaterThanPredicate(lowerBound) {
return function(numberToCheck) {
return (numberToCheck > lowerBound) ? true : false;
};
}

然后这样写:

var greaterThan10 = makeGreaterThanPredicate(10);
var greaterThan100 = makeGreaterThanPredicate(100);
alert(filter(greaterThan10, someRandomNumbers));
alert(filter(greaterThan100, someRandomNumbers));

  让我们来看看过个被makeGreaterThanPredicate返回的内部匿名函数。这个匿名函数使用了lowerBound变量,这可是一个传到makeGreaterThanPredicate的变量啊。根据作用域的规则,这个变量lowerBound的作用域超出了makeGreaterThanPredicate存在时的范围。但在这个例子中,匿名内容函数仍然可以访问到变量lowerBound,即使makeGreaterThanPredicate已经存在很久了。这就是我们所说的闭包–因为内部函数可以超范围地访问到所定义它的环境(函数)里的封闭区域(包括所有参数和变量)。

  在开始的时候,包闭也不见得是什么大不了的事情。但如果使用得当,就可以在把你的思想转化为代码的时候,为之添加进新的趣味。JavaScript的闭包的一个最有趣的应用就是:我们可以用它来模拟类的私有变量。

To be Continued…


参考文献:

  1. Java 理论与实践: 闭包之争
  2. 跨越边界: 闭包
  3. javascript语言中的闭包
  4. 在Javascript中,什么是闭包(Closure)


respondLeave a Reply