JavaScript:闭包是不是可以通过值而不是像 PHP 中的引用来访问封闭范围内的变量?

Posted

技术标签:

【中文标题】JavaScript:闭包是不是可以通过值而不是像 PHP 中的引用来访问封闭范围内的变量?【英文标题】:JavaScript: is it possible for closures to access variables in the enclosing scope by value rather than by reference like in PHP?JavaScript:闭包是否可以通过值而不是像 PHP 中的引用来访问封闭范围内的变量? 【发布时间】:2014-12-24 08:30:43 【问题描述】:

以下 javascript 代码演示了如何 JavaScript(闭包)函数访问变量 在他们的封闭环境中通过引用而不是 比值。

var sum; // global variable

function outer() 
  var hundred_more = 100;
  sum = function (a, b) 
    return a + b + (++hundred_more);
  ;
  sum2 = function (a, b) 
    return a + b + (++hundred_more);
  ;
  alert(hundred_more);

outer(); // define sum at the global scope and print 100
alert(sum(5, 10)); // 116
alert(sum(5, 10)); // 117
alert(sum2(5, 10)); // 118
alert(sum2(5, 10)); // 119
outer(); // redefine sum at the global scope and print 100
alert(sum(5, 10)); // 116
alert(sum(5, 10)); // 117
alert(sum2(5, 10)); // 118
alert(sum2(5, 10)); // 119

php 中的相同代码如下所示:

<?php

$sum = null; // global variable
$sum2 = null; // global variable

function outer() 
  global $sum;
  global $sum2;
  $hundred_more = 100;
  $sum = function ($a, $b) use (&$hundred_more) 
    return $a + $b + (++$hundred_more);
  ;
  $sum2 = function ($a, $b) use (&$hundred_more) 
    return $a + $b + (++$hundred_more);
  ;
  var_dump($hundred_more);

outer(); // define sum at the global scope and print 100
var_dump($sum(5, 10)); // 116
var_dump($sum(5, 10)); // 117
var_dump($sum2(5, 10)); // 118
var_dump($sum2(5, 10)); // 119
outer(); // redefine sum at the global scope and print 100
var_dump($sum(5, 10)); // 116
var_dump($sum(5, 10)); // 117
var_dump($sum2(5, 10)); // 118
var_dump($sum2(5, 10)); // 119

通过值而不是引用从封闭环境中传递变量 在 PHP 中,您只需在 use 关键字之后省略变量前面的和号 (&)。 这会导致值被复制到函数的闭包范围内 函数已定义,因此所有 'var_dumps' 都打印值 116。是否可以 以某种方式在 JavaScript 中实现相同的构造(将变量传递给 按值而不是按引用进行内部封闭)?

谢谢。

【问题讨论】:

我看到传递的唯一参数是数字常量510。你问的是代码的哪一部分? 我不是指函数的参数。我的意思是来自封闭范围的变量(比如 PHP 中 use 关键字之后的变量)。 【参考方案1】:

好吧,你可以为它创建另一个闭包...

function outer() 
    var hundred_more = 100;
    sum = (function(hundred_more)
        return function (a, b) 
          return a + b + (++hundred_more);
        ;
    )(hundred_more);
    sum2 = (function(hundred_more)
        return function (a, b) 
          return a + b + (++hundred_more);
        ;
    )(hundred_more);
    alert(hundred_more);

outer(); // define sum at the global scope and print 100
alert(sum(5, 10)); // 116
alert(sum(5, 10)); // 117
alert(sum2(5, 10)); // 116
alert(sum2(5, 10)); // 117
outer(); // redefine sum at the global scope and print 100
alert(sum(5, 10)); // 116
alert(sum(5, 10)); // 117
alert(sum2(5, 10)); // 116
alert(sum2(5, 10)); // 117

实际上并不是通过引用传递;他们只是引用同一个变量。通过创建一个新闭包,我们通过引用传递旧闭包,并获得解耦变量。

【讨论】:

感谢您的回答。据我了解您的回答,它利用了这样一个事实,即当将参数传递给 JavaScript 中的函数时,它是按值传递的(如下面的 sn-p 所示)。 函数 hello(a) a='hello';警报(一); var a = '世界';你好(一); / * 显示你好 * / alert(a); / * 显示世界 * / 这与 JavaScript 中的赋值语句不同,它只是创建对被赋值变量的引用而不是复制它。谢谢。

以上是关于JavaScript:闭包是不是可以通过值而不是像 PHP 中的引用来访问封闭范围内的变量?的主要内容,如果未能解决你的问题,请参考以下文章

具有格式化值而不是实际值的 EXCEL 公式

我可以从我的控制器返回一个值而不是视图吗?

Spark partitionBy |按列值而不是 columnName=value 保存

使用viewData值而不是ModelData手动设置表单数据

如何使用 Audiokit 对原始值而不是 MIDI 音符进行排序

在ArrayList中搜索相同的对象并合并价格值而不是添加