JavaScript中的范围链是什么?

时间:2017-06-25 17:31:17

标签: javascript

  

当我使用下面的代码时:

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.我知道这是与范围链相关的东西,因为我在谷歌搜索但没有完全理解。

1 个答案:

答案 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();