Javascript关闭与PHP关闭,有什么区别?

azi*_*ani 50 javascript php closures

JS中的闭包和PHP中的闭包有什么区别?他们几乎以同样的方式工作吗?在PHP中编写闭包时是否有任何需要注意的注意事项?

Ste*_*rig 116

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

// 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"
Run Code Online (Sandbox Code Playgroud)

要修复此通知,您必须使用以下use语法:

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

要使匿名函数以某种方式表现得像JavaScript对应物,您必须使用引用:

$a = 1;
$f = function() use (&$a) {
    echo $a;
};
$a = 2;
$f();
// will echo 2
Run Code Online (Sandbox Code Playgroud)

我认为这是JavaScript和PHP闭包之间最显着的区别.

第二个区别是,每一个JavaScript的关闭有一个this可用的情况下,这意味着,你可以使用this盖子本身内(尽管它往往是相当复杂,找出this实际上指的) - PHP的当前稳定版本(PHP 5.3)还不支持$this内一个闭包,但PHP即将推出的版本(PHP 5.4)将支持使用$this绑定和重新绑定$closure->bind($this)(有关详细信息,请参阅对象扩展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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

在JavaScript中你可以做到:

var fn = function() {};
fn.foo = 1;
fn.foo; // 1
Run Code Online (Sandbox Code Playgroud)

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

var fn = function() { return function() { alert('Hi');}}
fn()();    
Run Code Online (Sandbox Code Playgroud)

不是在PHP中:

$fn = function() { return function() { echo('Hi');};};
$fn()();     // syntax error
Run Code Online (Sandbox Code Playgroud)

  • 啊,干得好!我完全忘记了use关键字!为你+1!这些天我正在使用ColdFusion ...对我来说没有匿名功能:( (5认同)
  • 在PHP上下文中*匿名函数*和*闭包*可以互换使用,尽管存在差异.当前的实现甚至使用`Closure`作为所有匿名函数的底层类,而不管它们是真正的闭包(捕获外部上下文).术语*函数对象*在此问题上下文中并不重要. (2认同)
  • +1那么,你所说的是:PHP的实现者不知道Closure是什么?是的..我可以相信. (2认同)
  • @Louis No.他只说PHP有一个不同的,更直观的闭包实现,然后是JavaScript.这并不意味着任何一种实现都是错误的.他们只是不同. (2认同)