作为函数参数传递的匿名函数的范围

时间:2012-07-20 16:27:12

标签: javascript scope

鉴于以下代码,我应该在警报中看到什么?

var a = 100;
function afunc(infunc){
  a = 10;
  infunc.call();
}

afunc(function(){alert(a)});

我最初的想法是我的浏览器应该提醒100,因为变量a = 100将作为作为afunc参数传递的匿名函数的范围。但是这假设匿名函数实际上是在全局上下文中定义的。显然情况并非如此,因为浏览器提醒10。那么为什么在范围链中a = 10之前a = 10?

谢谢!

3 个答案:

答案 0 :(得分:6)

因为您在调用匿名函数之前将a设置为10。 a实际上是全局的,但你将它设置为10。

答案 1 :(得分:6)

  

那么为什么在范围链中a = 10之前的a = 10?

不是。您只定义了1个a变量,只是在被提醒之前从100更改为10

如果您希望a成为具有各自值的不同变量,则它们都需要var个关键字:

var a = 100
function afunc(infunc){
  var a = 10;
  infunc.call();
}

afunc(function(){alert(a)})​

答案 2 :(得分:1)

考虑以下示例:

var a = 100;

function afunc(infunc){
  a = 10;
  var f = function (){
    console.log(a);
  };
  f.call();
  infunc.call();
}

afunc(function (){ console.log(a); });

我们在a的范围内为afunc分配值10,然后依次记录a的值,依次调用两个函数。在这种情况下,您可能希望两个函数都将10记录为a的值,这实际上就是发生了什么。

在您的示例中,infunc将在与afunc中定义的任何本地函数基本相同的范围内执行,无论它实际定义在何处。由于您在较窄范围内为a分配了值,因此当您致电a时,这是infunc的值。

函数执行从其定义中保留一些范围,如下例所示:

function bfunc(){
  var b = 'hello';
  return function (){ console.log(b); };
}

afunc(bfunc());

此处,bfunc返回的匿名函数实际上是在afunc范围内调用的,但它仍然可以记录b的正确值,因为它在原始范围。如果您要更改afunc以为b分配不同的值,它仍会记录"hello",因为b中定义的afunc是不同的变量b中定义的bfunc