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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (9)

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闭包都有一个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

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

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 Closures是完整的对象,在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
用户回答回答于

我在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;
        }
    }

他们也非常适合......

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

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

扫码关注云+社区