【问题标题】:Functions dont get hoisted in an if else statement and for loop? [duplicate]函数不会在 if else 语句和 for 循环中被提升? [复制]
【发布时间】:2021-09-13 13:12:13
【问题描述】:

所以是的,这是你实际上不想做的事情,你总是想避免为不同的函数使用相同的名称 + 你不想再使用 var 来声明变量,因为这会导致很多的问题,但我很好奇为什么会发生这种情况!

我们知道用关键字var声明的变量和函数声明在创建阶段被提升到它们的函数范围的顶部,让我们先看一个变量的例子:

function f(){

console.log(p) // undefined

  if(true){
    var p = true;
  }
}

f()

由于我们在 if 块中声明了一个变量,并且由于 if 没有获得自己的执行上下文,所以我们得到了 undefined,我们声明的变量被提升到顶部,如下所示:

function f(){

// under the hood

var p = undefined;

console.log(p) // undefined

  if(true){
      p = true;
  }
}

f()

一切都说得通了,现在我们用函数来举例吧!

function f(){

let num = 5;

  if(num < 10){
    function a(){
      console.log('less than 10')
    }

    a()
  } else if(num < 20){
    function a(){
      console.log('less than 20')
    }

        a()
  }  else {
    function a(){
      console.log('something else')
    }

    a()
  }
}

f()

这会返回“小于 10”,但为什么呢?

我预计吊装会像这样发生:

function f(){
/* HOISTING 

 function a(){
      console.log('something else')
    }

// HOISTING COMPLETED
*/
let num = 5;

  if(num < 10){
 

    a()
  } else if(num < 20){
 
        a()
  }  else {
   

    a()
  }
}

f()

因为我们在每个 if-else 块 a 中都有同名的函数,所以无论我们将什么值放入 num 变量中,都应该使用最后一个!

我们知道如果我们有多个同名函数,则使用最后一个,因为这是最后一个被提升的函数,如本例所示:

function f(){

  b() // false

  function b(){
    console.log(true);
  }

  function b(){
    console.log(false);
  }
}

f()

那么 if-else 是怎么回事?

for 循环也是如此。 For 循环没有自己的执行上下文,因此使用 var 关键字和函数声明声明的变量也应该提升到其主函数范围的顶部,不是吗?但是这段代码不起作用:

function f(){

  ff();

  for (let i=0; i<1; i++){

    function ff(){
      console.log(true);
    }
  }
}

f();

我希望 for 循环“ff”中的函数被提升到我们的主 f 函数的顶部,但它没有!

(再一次,我知道定义两个同名函数,或者在声明之前调用函数,使用 var 关键字等是一种糟糕的做法。这些都是你一直想避免的事情,但我正在深入研究并试图解决此类问题)

【问题讨论】:

标签: javascript function for-loop var hoisting


【解决方案1】:

变量似乎在 for 循环中被提升,因此我们在第 3 行未定义!

f();

function f(){
console.log(v); // undefined

for (let i=0; i<1; i++){
  var v = true;
}

}

...但函数不会!

f();

function f(){

v(); **error: Uncaught ReferenceError: v is not defined**


for (let i=0; i<1; i++){
function v(){
console.log('hoisting wont happen')
}
}

}

【讨论】:

  • ES6 引入了块级函数。所以,他们不会被提升到他们的块范围之外,是的。话虽如此,网络兼容性规则基本上使使用起来非常烦人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多