为什么非静态变量表现得像静态?

时间:2015-09-19 10:15:20

标签: javascript function static

function emergency() {
    var ambulance = 100;
    var callAmbulance = function() { alert(ambulance); }
    ambulance++;
    return callAmbulance;
}
var accident = emergency();
accident(); // alerts 101

我指的是变量'ambulance'

当我调用accident();时,它应该调用emergency(),它应该使用声明的变量'ambulance' [考虑javascript中的全局范围内容,仍然可以将值设置为全局]但是使用旧值101而不是再次设置回100 - 表现得更像static var。

解释是什么?

2 个答案:

答案 0 :(得分:2)

你所拥有的是closure。这意味着函数可以访问在外部函数(或全局范围)中声明的变量。即使在“父”函数返回后,它仍保留访问权限。您需要了解的是,您没有获得副本。对该变量执行的更改对于您的内部函数是可见的,理论上这意味着您可以使用多个函数共享对同一变量的访问权。

function f () {
  var x = 0;

  function a() { x += 1; }
  function b() { x += 2; }
  function show() { console.log(x); }

  return {a:a, b:b, show:show};
}

var funcs = f();
funcs.a();
funcs.b();
funcs.show(); // 3

需要注意的一点是,对f的后续调用将创建一个新的范围。这意味着将创建一个 new x变量(新的a,b,show函数也将被创建)。

var newFuncs = f();
newFuncs.a();
newFuncs.show(); // 1

funcs.a();
funcs.show(); // 4

那么,你怎么得到副本?创建一个新范围。

function g () {
  var x = 0;
  var a;

  (function (myLocal) {
    a = function () { myLocal += 1; }
  }(x));

  x += 200;

  return a;
}

JS只有pass-by-value,所以当你调用匿名函数时,x变量的值将被复制到myLocal参数中。由于a将始终使用myLocal变量,而不是x,因此您可以确定对x变量执行的更改不会影响您的a函数。

如果您有任何机会来自PHP背景,那么您可能会习惯做类似

的事情
use (&$message)

允许修改反映在您的函数中。在JS中,默认情况下会发生这种情况。

答案 1 :(得分:1)

您正在创建此时未编译的函数定义:

var callAmbulance = function() { alert(ambulance); }

在您将其发送到被叫函数之前,您正在递增num:

ambulance++;

然后你将它发送到被叫函数:

return callAmbulance;

但无论你是否将它寄到那里,都没关系。以下语句执行或编译函数:

var accident = emergency();

这会在增量后获取当前ambulance101。这是创建函数但不执行它的预期行为。如果你不理解这种行为,请告诉我。我会更清楚地解释一下。