首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Javascript闭包与PHP闭包有什么不同?

Javascript闭包与PHP闭包有什么不同?
EN

Stack Overflow用户
提问于 2011-09-14 21:49:57
回答 3查看 5.9K关注 0票数 52

JS中的闭包和PHP中的闭包有什么不同?它们的工作方式大致相同吗?在用PHP编写闭包时有什么需要注意的地方吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-14 22:04:08

一个不同之处在于两者如何处理匿名函数在其中执行的上下文的存储:

代码语言:javascript
复制
// 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语法:

代码语言:javascript
复制
$a = 1;
$f = function() use ($a) {
    echo $a;
};
$a = 2;
$f();
// but this will echo 1 instead of 2 (like JavaScript)

要让匿名函数在某种程度上类似于JavaScript对应函数,您必须使用引用:

代码语言:javascript
复制
$a = 1;
$f = function() use (&$a) {
    echo $a;
};
$a = 2;
$f();
// will echo 2

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

的第二个不同之处在于,每个JavaScript闭包都有一个可用的this上下文,这意味着,您可以在闭包本身中使用this (尽管弄清楚this实际指的是什么通常是相当复杂的)-PHP的当前稳定版本(PHP5.3)还不支持在闭包中使用$this,但PHP的即将到来的版本(PHP5.4)将支持使用$closure->bind($this)$this绑定和重新绑定(有关更多信息,请参阅Object Extension RFC )。

第三个差异是两种语言处理分配给对象属性的闭包的方式:

代码语言:javascript
复制
// 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

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

代码语言:javascript
复制
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闭包不能有自己的属性:

代码语言:javascript
复制
$fn = function() {};
$fn->foo = 1;
// -> Catchable fatal error: Closure object cannot have properties

在JavaScript中,您可以执行以下操作:

代码语言:javascript
复制
var fn = function() {};
fn.foo = 1;
fn.foo; // 1

Javascript第五个不同之处:返回的闭包可以在中立即调用:

代码语言:javascript
复制
var fn = function() { return function() { alert('Hi');}}
fn()();    

不是在PHP中:

代码语言:javascript
复制
$fn = function() { return function() { echo('Hi');};};
$fn()();     // syntax error
票数 120
EN

Stack Overflow用户

发布于 2011-09-14 22:04:51

我在PHP中发现的唯一一件事(它非常酷,而且非常方便!)是在类中使用它们作为getters和setters的能力,这在以前一直是一个噩梦,JavaScript可以以相同的方式使用,但它们的行为与我看到的几乎相同。

我不确定两者之间的命名空间约定差异,但正如@Rijk指出的那样,PHP网站上有一个专门介绍它们的部分

代码语言:javascript
复制
<?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;
        }
    }

它们对……来说也很棒。

使用控制器循环访问项,而不是页面上的新for/each循环

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

让人讨厌的是……

你不能对它们进行类型转换,因为它们只是函数...

票数 4
EN

Stack Overflow用户

发布于 2011-09-14 21:52:37

它们的工作方式大致相同。下面是关于PHP实现的更多信息:http://php.net/manual/en/functions.anonymous.php

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

代码语言:javascript
复制
// return array of ids
return array_map( function( $a ) { return $a['item_id']; }, $items_arr );

并将其赋给一个变量:

代码语言:javascript
复制
$greet = function( $string ) { echo 'Hello ' . $string; }; // note the ; !
echo $greet('Rijk'); // "Hello Rijk"

此外,匿名函数“继承”定义它们的作用域-就像JS实现一样,有一个问题:您必须在use()中列出您想要继承的所有变量

代码语言:javascript
复制
function normalFunction( $parameter ) {
    $anonymous = function() use( $parameter ) { /* ... */ };
}

如果您想要修改原始变量,则可以作为参考。

代码语言:javascript
复制
function normalFunction( $parameter ) {
    $anonymous = function() use( &$parameter ) { $parameter ++ };
    $anonymous();
    $parameter; // will be + 1
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7417430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档