Javascript - 作用域链
Javascript - scope chain
我阅读了很多关于 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。
- console.log(2);
我的推理基于我的理解,函数 X 的 [[Scope]] 内部 属性 被设置为执行上下文,即函数 X 执行时的 运行。不基于声明函数 X 的位置。
b
定义在 foo
的范围内。
bar
是从 foo
的范围调用的,是的,但它是在 foo
的范围之外定义的。这意味着 bar
无法访问 b
.
图片通常可以提供帮助:
将每个红色方块视为一个 "scope"。 foo
和 bar
共享外部作用域,但它们不能访问彼此的内部作用域。
让我以不同的方式编写您的代码,以说明范围。
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'创建的范围内搜索它,而不是在[=]所在的范围内搜索它。 16=] 被调用。
我阅读了很多关于 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。
- console.log(2);
我的推理基于我的理解,函数 X 的 [[Scope]] 内部 属性 被设置为执行上下文,即函数 X 执行时的 运行。不基于声明函数 X 的位置。
b
定义在 foo
的范围内。
bar
是从 foo
的范围调用的,是的,但它是在 foo
的范围之外定义的。这意味着 bar
无法访问 b
.
图片通常可以提供帮助:
将每个红色方块视为一个 "scope"。 foo
和 bar
共享外部作用域,但它们不能访问彼此的内部作用域。
让我以不同的方式编写您的代码,以说明范围。
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'创建的范围内搜索它,而不是在[=]所在的范围内搜索它。 16=] 被调用。