Javascriptclosuresvs PHPclosures,有什么区别?

JS中的闭包和PHP中的闭包之间有什么区别? 他们几乎同样的方式工作? 在使用PHP编写闭包时是否需要注意一些注意事项?

一个区别是如何处理存储执行匿名函数的上下文:

// JavaScript: var a = 1; var f = function() { console.log(a); }; a = 2; f(); // will echo 2; // PHP $a = 1; $f = function() { echo $a; }; $a = 2; $f(); // will result in a "PHP Notice: Undefined variable: a in Untitled.php on line 5" 

要解决这个通知,你必须使用use语法:

 $a = 1; $f = function() use ($a) { echo $a; }; $a = 2; $f(); // but this will echo 1 instead of 2 (like JavaScript) 

要使匿名函数像JavaScript对应程序那样行为,您必须使用引用:

 $a = 1; $f = function() use (&$a) { echo $a; }; $a = 2; $f(); // will echo 2 

我认为这是JavaScript和PHPclosures之间最显着的区别。

第二个区别在于,每个JavaScript闭包都有一个可用的上下文,这意味着您可以在闭包本身内部使用它(尽pipe弄清楚this实际上指的是什么)通常很复杂 – PHP当前的稳定版本(PHP 5.3)没有但是在一个闭包中支持$this ,但是即将到来的PHP版本(PHP 5.4)将支持$this绑定,并使用$closure->bind($this)重新$closure->bind($this) (请参阅Object Extension RFC获取更多信息。

第三个区别是两种语言如何处理分配给对象属性的闭包:

 // JavaScript var a = { b: function() {} }; ab(); // works // PHP $a = new stdClass(); $a->b = function() {}; $a->b(); // does not work "PHP Fatal error: Call to undefined method stdClass::b() in Untitled.php on line 4" $f = $a->b; $f(); // works though 

如果将闭包分配给类定义中的属性,情况也是如此:

 class A { public $b; public function __construct() { $this->b = function() {}; } public function c() { $this->b(); } } $a = new A(); // neither $a->b(); // nor $a->c(); // do work 

第四个区别: JavaScript闭包是完整的对象,在PHP中它们是受限制的对象。 例如,PHP闭包不能拥有自己的属性:

 $fn = function() {}; $fn->foo = 1; // -> Catchable fatal error: Closure object cannot have properties 

而在JavaScript中,你可以这样做:

 var fn = function() {}; fn.foo = 1; fn.foo; // 1 

第五个区别:可以立即在Javascript中调用返回的闭包:

 var fn = function() { return function() { alert('Hi');}} fn()(); 

不在PHP中:

 $fn = function() { return function() { echo('Hi');};}; $fn()(); // syntax error 

我在PHP中发现的唯一的东西就是能够将它们作为getter和setter来使用,而这些是前所未有的噩梦,JavaScript也可以以同样的方式使用,但它们两者的行为几乎与我见过的一致。

我不确定两者之间的命名空间惯例的差异,但是@Rijk指出,PHP网站上有一节专用于它们

 <?php class testing { private $foo = 'Hello '; public $bar = 'Bar'; #Act like a getter and setter! public static $readout = function ($val = null) { if (!empty($val)) { testing::$readout = $val; } return testing::$readout; } } 

他们也非常适合…

使用控制器循环播放项目,而不是在页面上使用新的/每个循环

非常适合作为参数提供给函数/类

有什么恼人的是…

你不能形容他们,因为他们只是function…

他们的工作方式也差不多。 下面是关于PHP实现的更多信息: http : //php.net/manual/en/functions.anonymous.php

您可以使用闭包(在PHP中称为“匿名函数”)作为callback:

 // return array of ids return array_map( function( $a ) { return $a['item_id']; }, $items_arr ); 

并将其分配给一个variables:

 $greet = function( $string ) { echo 'Hello ' . $string; }; // note the ; ! echo $greet('Rijk'); // "Hello Rijk" 

而且,匿名函数“inheritance”了它们被定义的范围 – 就像JS实现一样, 有一个问题 :你必须在use()列出你想要inheritance的所有variables:

 function normalFunction( $parameter ) { $anonymous = function() use( $parameter ) { /* ... */ }; } 

并作为参考,如果你想修改orignalvariables。

 function normalFunction( $parameter ) { $anonymous = function() use( &$parameter ) { $parameter ++ }; $anonymous(); $parameter; // will be + 1 }