封口很漂亮!它们解决了许多匿名函数带来的问题,并使真正优雅的代码成为可能(至少只要我们谈论 php)。
javascript 程序员一直使用闭包,有时甚至不知道它,因为绑定变量没有明确定义——这就是 php 中的“使用”。
现实世界的例子比上面的例子更好。假设您必须按子值对多维数组进行排序,但是键会发生变化。
<?php
function generateComparisonFunctionForKey($key) {
return function ($left, $right) use ($key) {
if ($left[$key] == $right[$key])
return 0;
else
return ($left[$key] < $right[$key]) ? -1 : 1;
};
}
$myArray = array(
array('name' => 'Alex', 'age' => 70),
array('name' => 'Enrico', 'age' => 25)
);
$sortByName = generateComparisonFunctionForKey('name');
$sortByAge = generateComparisonFunctionForKey('age');
usort($myArray, $sortByName);
usort($myArray, $sortByAge);
?>
警告:未经测试的代码(我没有安装 php5.3 atm),但它应该看起来像这样。
有一个缺点:很多 php 开发人员在遇到闭包时可能会有点束手无策。
为了更多地理解闭包的好处,我会给你另一个例子——这次是在 javascript 中。问题之一是范围和浏览器固有的异步性。特别是,如果涉及到window.setTimeout();(或-interval)。所以,你给 setTimeout 传递了一个函数,但是你不能真正给任何参数,因为提供参数会执行代码!
function getFunctionTextInASecond(value) {
return function () {
document.getElementsByName('body')[0].innerHTML = value; // "value" is the bound variable!
}
}
var textToDisplay = prompt('text to show in a second', 'foo bar');
// this returns a function that sets the bodys innerHTML to the prompted value
var myFunction = getFunctionTextInASecond(textToDisplay);
window.setTimeout(myFunction, 1000);
myFunction 返回一个带有某种预定义参数的函数!
说实话,自 5.3 和匿名函数/闭包以来,我更喜欢 php。命名空间可能更重要,但它们没有那么性感。