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

JavaScript: is it possible for closures to access variables in the enclosing scope by value rather than by reference like in PHP?

提问人:John Sonderson 提问时间:10/29/2014 更新时间:2/23/2015 访问量:111

问:

以下 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 中实现相同的结构(变量传递给 按值而不是按引用进行内部闭包)?

谢谢。

JavaScript PHP 闭包 按引用 值传递

评论

1赞 Pointy 10/29/2014
我看到传递的唯一参数是数值常量和 .你问的是代码的哪个具体部分?510
0赞 John Sonderson 10/29/2014
我不是说函数的参数。我的意思是来自封闭范围的变量(例如PHP中use关键字后面的变量)。

答:

1赞 Scimonster 10/29/2014 #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

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

评论

0赞 John Sonderson 10/29/2014
谢谢你的回答。据我了解,您的答案是,它利用了这样一个事实,即当参数传递给JavaScript中的函数时,它是按值传递的(如下面的代码片段所示)。
0赞 John Sonderson 10/29/2014
函数 hello(a) { a='hello'; alert(a); } var a = 'world';你好(a);/ * 显示 hello * / alert(a);/ * 显示世界 * /
0赞 John Sonderson 10/29/2014
这与 JavaScript 中的赋值语句不同,后者只是创建对被赋值变量的引用,而不是复制它。谢谢。