JS 提升如何与块语句一起使用?

How JS hoisting works with block statement?

在接下来的代码片段中,我只是想了解为什么 console.log(abc in this); 是 print true ,但在下一行 console.log(abc); 得到 undefined

console.log(this.abc);//undefined
console.log(abc in this);//true
console.log(abc);//undefined
{
    function abc(){
        console.log("hello");
    }
}
console.log(abc); //ƒ abc(){console.log("hello");

你们谁能解释一下 Hoisting 和 Block 语句在这种情况下是如何工作的?

草率模式下,this指的是全局对象。像这样的普通 non-function 块中的函数会将其变量名提升到 outer 范围,但不会分配实际函数到外部变量(到 window 属性)直到执行内部块。

详情请看这里:

正如在另一个问题中所解释的那样,对于解释器来说,您的代码看起来像这样:

window.abc = undefined; // top-level hoisting assigns to window properties
console.log(window.abc); // undefined
console.log(window.abc in window); // true
console.log(window.abc); // undefined
{
  var _abc = function abc() {
    console.log("hello");
  };
  window.abc = _abc;
}
console.log(window.abc); //ƒ abc(){console.log("hello");

abc in this之所以为真,是因为abc已经初始化为window对象的属性,但它还没有被赋值。这与此处发生的情况类似:

const obj = { foo: undefined };
console.log('foo' in obj);

简单地说,使用 console.log(abc in this); 它检查它是否存在,它确实存在,因此记录 true,虽然你还不能访问它,因此得到 undefined另外两个 console.log 在函数声明之前执行。

如果你想知道为什么会发生这种情况,答案很简单,提升将所有声明移动到他的范围的顶部,所以:

console.log(this.abc); //undefined
console.log(abc in this); //true
console.log(abc); //undefined

function abc() {
  console.log("hello");
}

console.log(abc); //ƒ abc(){console.log("hello");

所以在内部函数中,函数 abc() 在当前范围的顶部声明,几乎保持在相同的位置,但只是声明,所以当您尝试访问时,先声明 var abc 然后分配在底部他已经知道函数,在第一个 console.log 那里你得到 undefined

console.log(abc) 函数 _abc 尚未贴标,但在第二个示例中您可以访问它,因为它访问 windows 对象并获取 abc。

所以简而言之,javascript 首先初始化变量,因为在第二个 console.log 所有变量都已经声明,并且它们在 window 对象中声明,访问 abc这很好用。