閉鎖は美しいです!それらは匿名関数に付随する多くの問題を解決し、本当にエレガントなコードを可能にします(少なくとも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をインストールしていません)、しかしそれはそのようなもののように見えるはずです。
欠点が1つあります。多くのPHP開発者は、クロージャーに直面した場合、少し無力になる可能性があります。
クロージャーの便利さをさらに理解するために、別の例を挙げましょう。今回はJavaScriptです。問題の1つは、スコープとブラウザ固有の非同期です。特に、それが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と匿名関数/クロージャーがもっと好きです。名前空間の方が重要かもしれませんが、それほどセクシーではありません。