Javascript闭包和PHP闭包,有什么区别?

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和PHP闭包之间最显着的区别。

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

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

// JavaScript
var a = {
    b: function() {}
};
a.b(); // 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 Closures不能有自己的属性:

$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

转载注明原文:Javascript闭包和PHP闭包,有什么区别? - 代码日志