0

我阅读了许多关于 javascript 作用域链的文章,我认为我对它有一个不错的理解。然而,一个非常简单的练习让我意识到我根本不理解它。

我创建了以下代码。

function foo () {
  var b = 2;

  bar()

} 

function bar () {
  console.log(b);

}

foo();

此代码给出了参考错误。但是,我认为它仍然会打印出 2。我的理由如下:

  • foo 和 bar 的函数声明。
  • Foo 被执行,这会创建一个新的执行上下文。Foo 的内部属性 [[Scope] 设置为全局。
  • var b 被提升。
  • var b 被赋值为 2。
  • bar 在 foo 执行上下文中执行。因此,我假设 bar 函数的内部属性 [[Scope]] 将设置为 foo。
  • b 未在函数 bar 中定义,因此查找范围链并找到值 b = 2。
  • 控制台.log(2);

我的推理是基于我理解函数 X 的 [[Scope]] 内部属性设置为在函数 X 执行时正在运行的执行上下文。不基于函数 X 的声明位置。

4

2 回答 2

3

b foo's 范围内定义。

bar是从foo' 的范围调用的,是的,但它是在foo' 范围之外定义的。这意味着bar无法访问b

图像通常可以提供帮助:

在此处输入图像描述

将每个红色方块视为一个“范围”。foobar共享外部范围,但他们不能访问彼此的内部范围。

于 2017-05-03T11:44:45.490 回答
1

让我以不同的方式编写您的代码,以说明范围。

var scope = {};
scope.foo = function() {
  var b = 2;   
  scope.bar()   
} 

scope.bar = function() {
// this will look for a property 'b' defined in the bar method, but it doesn's exist
  console.log(b); 
// changing the console.log call to match the changes made above, means it will 
// look like this
  console.log(scope.b)
// but now scope.b is also not defined
}

scope.foo();

换句话说,当您尝试访问 'bar' 中的 'b' 时,它将在创建 'bar' 的范围内搜索它,而不是在调用 'bar' 的范围内。

于 2017-05-03T12:07:51.187 回答