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 中实现相同的构造(将变量传递给 按值而不是按引用进行内部封闭)?
谢谢。
【问题讨论】:
我看到传递的唯一参数是数字常量5
和10
。你问的是代码的哪一部分?
我不是指函数的参数。我的意思是来自封闭范围的变量(比如 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 中的引用来访问封闭范围内的变量?的主要内容,如果未能解决你的问题,请参考以下文章
Spark partitionBy |按列值而不是 columnName=value 保存
使用viewData值而不是ModelData手动设置表单数据