分享一道面试题,请指点结果为何是undefined

if(!("a" in window)){
    var a = 10;
}
console.log(a); // undefined

阅读 5.2k
9 个回答
因为变量提升到作用域顶部

//变量提升
var a ;

//此时 a 为全局变量  a in window 为 true

if(!("a" in window)){
 var a = 10;
}
console.log(a); // undefined

首先弄明白in运算符,可以在MDN中查看。如果指定的属性在指定的对象或其原型链中,则in 运算符返回true。

然后就是js引擎执行js语句机制了,js引擎运行时会执行三步操作,第一步是先检查你的js代码有没有低级的语法错误,第二步是预编译,第三步是根据代码顺序解释一句执行一句。

预编译就是在执行代码会把所有的变量声明和函数声明预先处理。当你写了一句var a = 1时,javascript会当成两个操作(变量声明和变量赋值):var a;和a = 1;第一句(变量声明)是在预编译中执行的,此时只是声明了a这个变量,没有赋值操作,所以此阶段a的值为undefined。等预编译结束,才开始上面的第三步解释执行js代码。

所以根据执行先后上面的代码可以分解为下面的代码:

// 先进行预编译

var a; // 此时a的值为undefined

// 预编译结束  开始解释执行代码

if(!("a" in window)){ // 变量a此时已经存在,所以!("a" in window)为false
    a = 10; // 跳过不执行  a的值还是undefined
}

console.log(a)  // undefined

因为if 条件不成立,所以a 并没有赋值。但是因为变量声明的作用域提升,所以var a的声明提升到了顶部。
于是 a 就是声明但未赋值的变量 ,为undefined

只要有var,不等到方法执行,就会把变量提升的方法的开始之处,这里就相当于提升到了window的作用域中。

额.刚刚被点了灭重新编辑一下答案.
我的意思是.
在if或者for作用域里面通过var的形式去定义的一个变量,

这个变量是等同于
在if或者for所在的作用域里面去定义.而且满足变量提升的原则

谢谢大家的回答,原来以为自己对变量提升的概念已经很熟悉了,没想到遇到问题还是看漏了眼。

主要原因是以为有块作用域看偏了吧,

新手上路,请多包涵

由于变量提升,var a会在一开始的时候就出现,此时值为undefined,然后执行到if时,由于a已经在window中定义了,即开辟了一块内存,所以判断结果为真,然后!真就变为假,所以跳过了赋值语句,最后console的是未赋值的a,结果为undefined

使用var导致此处不存在作用域,var a = 10等同于在if语句外面设置,var设置变量有个变量提升,所以if判断时a已经被定义但是未赋值,导致if语句判断结果为flase不能对a进行赋值,下面的结果为undefined

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题