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

2024-05-11

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 syntax:

$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 https://wiki.php.net/rfc/closures/object-extension?s%5B%5D=closure了解更多信息。)

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

// 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 闭包不能拥有自己的属性:

$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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript 闭包与 PHP 闭包,有什么区别? 的相关文章

随机推荐

  • Java 阻止列表实现

    我在 SO 和 Google 上搜索了这个问题的答案 但到目前为止找不到合适的解决方案 我目前正在研究图形路由问题中的 LayerManager 管理器负责提供和重置一组固定的层 我想使用阻止列表来实现消费者 生产者模式 以便只要没有可用的
  • 什么是 C# 类 StreamContent?

    这可能在网络上的某个地方有解释 但我找不到它 StreamContent 到底是什么 我试图理解 C 但我无法正确理解一些 WebAPi 示例 因为我不明白 StreamContent 是什么 一个完整解释它的链接 而不是像 MSDN 那样
  • C# NetworkStream.Read 奇怪之处

    谁能指出这段代码中的缺陷吗 我正在使用 TcpClient 检索一些 HTML 与 IIS 服务器通信时 NetworkStream Read 似乎永远不会完成 如果我改用 Fiddler 代理 它可以正常工作 但是当直接与目标服务器对话时
  • 如何诊断这些 PHP 代码覆盖分段和 zend_mm_heap 损坏错误

    我一直很高兴在我的 Ubuntu 机器上编码 这是一台拥有大量内存的强大机器 我正在研究 4 个新课程 一边编写和运行单元测试 在某些时候 我注意到 虽然单元测试完成得很好 但代码覆盖率却没有 在消息 正在生成代码覆盖率报告 等 之后 我会
  • 内部注册 vs. OpenID vs. Google Friend Connect vs. Facebook Connect vs.(等等)

    我正在尝试决定如何允许用户注册我的网站 有 openID clickpass facebook connect googlefriendconnect 等 或者是老式的内部 输入用户名 电子邮件 密码等 简要地看一下如何设置 OpenID
  • Objective C - 动态属性的respondsToSelector

    我目前面临的问题是检查对象 NSManagedObject 的属性是否存在 不幸的是方法 MyObject class respondsToSelector selector myProperty 总是返回NO 我认为这是因为CoreDat
  • TX 未发送至公证服务的情况有哪些?

    交易未提交公证服务的情况有哪些 尽管进度跟踪器显示公证步骤 但我们注意到在某些情况下交易并未真正发送到公证服务 例如 没有时间窗口的状态创建 从 Corda 3 3 开始 如果 Tx 没有输入且没有时间窗口 则不会将其发送给公证人进行签名
  • 添加 Javascript 按钮来更改 iframe 的内容

    我正在尝试创建此页面 其中有一个 Iframe 并且我想添加一个按钮来显示 iframe 中的下一页 以及一个按钮来显示 iframe 中的上一页 我总共有 4 个页面要在名为 1 html 2 html 3 html 4 html 的 i
  • 我应该使用哪个 Linux 发行版作为 Xen 主机? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我为家庭办公室订购了一台服务器 我想用 Xen 对其进行分区 我认为这将使事情保持干净并且更容易维护 我将运行 MySQL PostgreSQL
  • 为什么 MATLAB 本机函数 cov(协方差矩阵计算)使用与我预期不同的除数?

    给定一个 M 维和 N 个样本的数据矩阵数据 例如 data randn N M 我可以计算协方差矩阵 data mu data ones N 1 mean data cov matrix data mu data mu N 如果我使用原生
  • 查找PID所属的tmux会话

    我正在使用 htop 所以看看哪些进程占用了大量内存 以便我可以杀死它们 我有很多 tmux 会话和很多类似的流程 如何检查 PID 位于哪个 tmux 窗格中 以便确定我正在杀死我想杀死的东西 鉴于PID下面一行是目标 pid 号 tmu
  • SQL Server - 删除语句增加日志大小

    我有一个LOGGIN数据库很大 400 GB 它有数百万行 我刚刚跑了一个delete该语句花费了 2 5 小时并删除了可能数百万行 delete FROM DB dbo table where Level not in info erro
  • R中一张图中的多个条形图

    我是 R 初学者 我需要创建一个像这样的图表 https i stack imgur com az56z jpg https i stack imgur com az56z jpg 我不知道如何生成整个数据集 基本思想是某个外显子 ID 会
  • 传递 oauth 令牌请求的授权标头

    我使用java实现oauth来获取未经授权的请求令牌 如何传递授权标头中的参数 我需要通过 GET request token HTTP 1 1 Host photos example net 80 Authorization OAuth
  • 如何在 GTX 560 及更高版本上使用 OpenGL 进行立体 3D?

    我正在使用在 Windows 7 上运行的开源触觉和 3D 图形库 Chai3D 我重写了该库以使用 Nvidia nvision 执行立体 3D 我将 OpenGL 与 GLUT 一起使用 并使用 glutInitDisplayMode
  • 将数组从控制器传递到视图

    I have UIView UI视图控制器 在 UIViewController 中 我需要能够将项目插入到 6 个整数的固定数组中 然后 我需要将此数组传递给视图 以便它分析该数组并适当地更新屏幕 我该怎么做呢 我尝试过使用标准 C 数组
  • 为什么在特征中返回“Self”可以工作,但返回“Option”需要“Sized”?

    这个特征定义编译得很好 trait Works fn foo gt Self 然而 这确实会导致错误 trait Errors fn foo gt Option
  • Google Map Android API v2 无法在 Play 商店应用程序中显示地图

    我正在与Google Map Android API v2在 Android 应用程序中 它可以很好地与未签名的应用程序在不同的设备上 但是 当我签署 apk 并将应用程序上传到 Play 商店时 下载的应用程序显示白屏而不是地图 您使用什
  • 如何在打字稿中的类方法上强制执行函数类型接口?

    许多方法的class我隐含地写着同样的功能类型 https www typescriptlang org docs handbook interfaces html function types 我想要做的是强制执行此函数类型 以便我可以明
  • Javascript 闭包与 PHP 闭包,有什么区别?

    JS 中的闭包和 PHP 中的闭包有什么区别 它们的工作方式几乎相同吗 在 PHP 中编写闭包时有什么需要注意的注意事项吗 一个区别是两者如何处理存储执行匿名函数的上下文 JavaScript var a 1 var f function