在下面的snipet中,我只是想了解为什么console.log(abc in this);
打印为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语句是如何工作的吗?
答案 0 :(得分:2)
在草率模式下,this
指的是全局对象。像这样的普通非函数块中的函数将其变量名提升到外部作用域,但实际函数不会被赋值给外部变量(到窗口属性)直到内部块被执行。
详情请见此处:
What are the precise semantics of block-level functions in ES6?
正如其他问题所解释的那样,对于解释器,您的代码看起来像这样:
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
已将初始化为窗口对象的属性,但尚未为其分配值。它与此处发生的情况类似:
const obj = { foo: undefined };
console.log('foo' in obj);
答案 1 :(得分:1)
简单地说,使用console.log(abc in this);
检查它是否存在,因此记录true
,但是您无法访问它,因此获取undefined
两个console.log
在函数声明之前执行。
答案 2 :(得分:-1)
如果您想知道为什么会发生这种情况,答案很简单,提升将所有声明移到他的范围顶部,所以:
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中
console.log(abc)函数_abc尚未进行十分转换,但在第二个示例中,您可以访问它,因为它访问了windows对象并获取了abc。
所以简而言之,javascript首先初始化变量,因为在第二个console.log中已经声明了所有变量并且它们在window对象中声明,访问abc就可以了。