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代码演示了如何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中实现相同的构造(将变量传递给通过值而不是通过引用的内部闭包)?

谢谢。

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

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

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