我们知道每个函数都会创建自己的上下文,并且可以拥有自己的局部变量和事物。
因此,我们假设var a = [5]
在最顶层函数上下文的上下文中编写 ,将使其可以被我们可能编写的任何新嵌套函数的上下文访问和访问。
这就是我们遇到最有可能“未记录”和“意外”的行为的地方。
op的1at示例
function bar(){
if(!a) {
var a = [1,2];
}
console.log(a);
}
>> 1,2
让它返回本地值 1,2。我们可以看到bar函数上下文的if条件将宿主函数变量a视为未定义,因此它将!a否定为true。
这是为什么?一位评论员坚持要吊装。但是什么吊装?在同一函数的两个版本中,提升原则绝对不会干扰最终结果或行为,唯一的区别在于条件参数:一个检查 'a' 是否为false,另一个检查是否为true。
吊装!什么吊装?如果是为了“提升”- !a操作应该明确地返回false,因为 a 已经在更高的上下文上定义了一个真实值,该更高的上下文可以访问主机的任何和每个较低的上下文函数。但恰恰相反
由于 if(!a [false] ) 因此条件返回为true,它允许使用 var 键执行同名变量的新声明,就好像它遥不可及或不存在在更高的范围内。
它不应该。但它应该。
现在在条件中不否定 if 参数的情况下尝试同样的事情,我们将得到一个错误和一个赋值失败,如下所示:
function bar(){
if(a) {
var a = [1,2];
}
console.log(a);
}
>> undefined
[!same as when using if(!!a) ] 除了现在我们询问 a 是否为真之外,我们什么都没做,这样我们就可以创建一个新的局部 'a' 变量,其值为 [1,2];
到底是怎么回事?!if条件明确需要a参数为真才能继续进行,它是
查找并“向下爬”到函数bar的本地上下文。
由于某种原因,它被视为尝试重新声明宿主函数的变量并拒绝在本地上下文中初始化并为具有相同名称的新变量赋值。这是一个混乱,因为条件现在指的是它拒绝声明和分配值给本地 a 的主机变量。
但是,在控制台日志中,返回了一个局部变量 a 并且它是undefined。
这是出乎意料的;矛盾的;挑衅但看似正确!这是正确的,因为本地a变量已初始化,但开始时没有正确获取值。我们试图从更高的上下文中重新声明它,但这是不允许的。
唯一的好处是 - 跨浏览器的行为似乎是统一的。