JavaScript:函数及其范围/词汇环境是如何传播的?

时间:2016-02-06 17:37:55

标签: javascript function scope closures

我正在玩闭包,并且在理解内部函数如何访问外部词汇环境方面没有任何问题:

function outer() {
  var bar = 0;
  function inner() {
    console.log(bar);
  }
  inner();
}
outer();    // prints '0'

但是我得到的是:

function foo() {
  return function inner() {
    console.log(bar);
  }
}
function outer() {
  var bar = 0;
  var fakeInner= foo();    // not the same as "var fakeInner= function () { console.log(bar); }"
  fakeInner();
}
outer();    // ReferenceError: bar is not defined

我在这里尝试定义"一个"内部功能" fakeInner通过将其分配给从外部函数返回的函数表达式。

我以前认为JavaScript会在" copy"内部创建fakeInner。其代码类似于:var fakeInner= function () { console.log(bar); },然后可以访问bar,但事实并非如此 - 当调用fakeInner时,JavaScript会追溯到其定义即可。我理解正确吗?也就是说,函数对象(声明或表达式)仅仅是对它们的定义点的引用,并且传递它们不会改变它们的词法环境(因此内部函数必须使用显式语法定义)?

3 个答案:

答案 0 :(得分:1)

是的,函数只能访问自己的词法环境 - 从定义它们的位置开始。 JavaScript没有dynamic scope,其中函数可以对调用它的作用域进行任何类型的访问。

这是通过将范围附加到函数对象来实现的,它是闭包的一部分。

答案 1 :(得分:1)

在此示例中,

function outer() {
  var bar = 0;

  function inner() {
    console.log(bar);
  }
  inner();
}
outer();

范围barouter函数,可用于其中定义的所有函数。

function foo() {
  return function inner() {
    console.log(bar);
  }
}

function outer() {
  var bar = 0;
  var fakeInner = foo(); // not the same as "var fakeInner= function () { console.log(bar); }"
  fakeInner();
}
outer();

在此示例中,再次bar可在outer内访问,但foo在其外部。因此抛出了引用错误。

另请参阅What is the scope of variables in JavaScript?以获取更多信息。

答案 2 :(得分:0)

内部函数的范围是它自己的外部函数。不是从中调用的函数。