if块是否在函数范围内创建新的局部范围?

时间:2017-04-29 10:31:55

标签: javascript

例如:

function example() {
   console.log("outside the if block above function b declaration"+b()); 
  function a() {
   return "you invoked function a";
  } 
  if (true) {
    console.log("inside the if block"+a());
    console.log("inside the if block above function b declaration"+b());
    function b() {
      return "you invoked function b";
    } 
  }
}

当我调用这个example()函数时,我得到一个错误,b是未定义的,但当我删除第二行调用if块中定义的函数b时它是否一切正常?

3 个答案:

答案 0 :(得分:6)

是和否。关键字let确实支持块中的本地范围。关键字functionvar适用于功能级别范围。它们在执行之前编译块时定义一个标识符。所以你通常可以调用声明之上的函数。

在您的示例中,函数是有条件声明的。它将在评估条件后声明,并且执行内部块之前声明。但是当它被声明时,它在整个函数的范围内是有效的。尝试移动if-block下面的invokation,它将被知道并执行。

答案 1 :(得分:2)

不,它没有。如果块仍然限制在其容器中。您的函数B未定义,因为定义它的代码在被if语句阻止时永远不会被执行。但是,一旦删除了if语句,就会执行定义函数的代码,定义函数。

这是jsfiddle demonstrating the concept

function defining() {
    ifstmt = true;
    if(ifstmt) {
        var ifscope;
        ifscope = "yes";
    }
    console.log(ifscope); // logs "yes"
}

function notDefining () {
    ifstmt = false;
    if(ifstmt) {
        var ifscope;
        ifscope = "no";
    }
    console.log(ifscope); // logs undefined
}

defining()
notDefining()
defining()中的

变量ifscope已定义,但显然不限于if语句的范围。在notDefining()中,将跳过定义ifscope的代码,因此console.log将返回undefined。

答案 2 :(得分:0)

正如Michael.Lumley在答案中指出的那样,通常需要代码来定义在执行代码之前发生的事情。但是,Javascript支持" hoisting",它使编码器能够在定义之前调用一段代码。(更多关于提升 - https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) 因此,以下代码可以正常工作:

example()
function example() {
  console.log("outside the if block above function b declaration"+b()); 
  if (true) {
    console.log("inside the if block"+a());
    console.log("inside the if block above function b declaration"+b());
  }
}
function a() {
   return "you invoked function a";
  }
function b() {
      return "you invoked function b";
    } 

这是jsfiddle - https://jsfiddle.net/px2ghrgy/

但是,你的代码显然不会起作用,因为似乎条件似乎不支持吊装。原因是范围,即,虽然函数在一个封闭范围(全局或函数内)中提升,但它不会发生在条件(if / else)中。 您会发现此答案也相关 - > https://stackoverflow.com/a/35250887/7374117