当我使用下面的代码时:
function a(){
var q = 1;
function b(){
console.log(q);
}
b();
}
var q= 2;
a();
它输出为1。 但是当我使用下面的代码时:
function b(){
console.log(q);
}
function a(){
var q = 1;
b();
}
q= 2;
a();
输出是2.当我使用下面的代码时:
function a(){
function b(){
console.log(q);
}
b();
}
var q= 2;
a();
我再次得到输出为2.我知道这是与范围链相关的东西,因为我在谷歌搜索但没有完全理解。
答案 0 :(得分:0)
范围链只是声明标识符的位置,搜索该位置以解析标识符的值。
在声明某些内容时,区分声明某些内容与之间的区别非常重要。仅仅因为您在使用q
的函数调用之前声明q
并不意味着将使用的q
- 可能存在多个q
变量,每个都存在它们自己的范围。
在我们查看您的示例之前,请想一想这个场景。你在一个大房间里,分成几个小房间,可以容纳两个工人。你和你的同事“乔”共用一个小隔间(因为你在那里,这是你的本地范围,你和乔分享)。如果你和Joe同时坐在你的共用隔间里,而你想与Joe谈话,你只会说“嘿Joe”,Joe会立即回应。但是,如果乔起身在办公室水冷却器上取水怎么办?如果你然后说“嘿乔”,他就不会在你的小隔间范围内被发现,所以你必须将你的搜索扩大到整个办公室(一个更高的范围,包含你的隔间所在的范围)。但是,通过将搜索范围扩大到下一个更高的范围(向上扩展范围链),您最终会找到Joe。现在想象一下,水冷却器在同一楼层的两个办公室之间共享。你不会在你的小隔间找到乔,他不会在你的办公室,所以你必须再次扩大你的搜索范围,包括你可以看到的其他范围(隔壁的办公室)。
还在我身边吗?现在,这里有一个皱纹...如果每个地方都有不同的“Joe's”,而你想与之交谈的Joe是在另一个办公室怎么办?当你说“嘿乔!”时,最接近的人会回复,但这可能不是你想到的乔。这就是您的q
变量所发生的情况。您在不同的范围级别声明了多个,并且您期望的那个与您调用它的范围最接近。
function a(){
// q is declared in this scope and this is the next highest scope to where it is
// used for the console.log, so 1 is the output
var q = 1;
function b(){
// q isn't declared in this function's scope, so the next higher scope
// needs to be checked.
console.log(q);
}
b();
}
// Even though this code runs just before the function call,
// this is creating a different "q" variable in the higest scope
// -- the global scope. When the function runs, it won't need
// to search all the way up to this level to find a declaration
// for q, so 2 isn't what is outputted
var q= 2;
// Now, run the function
a();
function b(){
// Here, there is no q in this local scope,
// so again, the next highest scope is searched.
// Since this is NOT a nested function, the next highest
// scope is the global scope and the q in that scope is found
// producing 2 as output
console.log(q);
}
function a(){
// Create a local q variable that only is accessible from here
var q = 1;
// Invoke the b function
b();
}
// Global q is being set
q = 2;
// Invoke the a function
a();
function a(){
// There is no q in this scope, so the next highest scope (the global scope)
// is checked.
function b(){
// There is no q in this scope, so the scope of a is checked
console.log(q);
}
b();
}
// Not only is this the Global q, but it's the only q declared
var q= 2;
a();