变量提升是JavaScript面试题中经常被问到的题目类型,因为这其中包含着对整个JavaScript程序运行机制的理解,如果掌握不好,那么编写代码或者调试程序都会很成问题,关于变量提升的原理机制,推荐参考JavaScript执行上下文的运行原理,对变量提升的分析都是基于执行上下文的机制的,所以基本上需要理解执行上下文的机制才行,下面我们一起看一些关于变量提升的经典面试题。
变量提升面试题案例一:
var value = 2019;
function fn(){
console.log(value);
var value = {name: "Time"};
console.log(value);
}
fn(); // 指向该函数会输出什么?
console.log(value); // 输出?
上面代码中,全局变量和fn函数内部都定义了一个value变量,问题是:三个console.log分别输出什么?答案是:
undefined
{name: "Time"}
2019
为什么呢?首先JavaScript程序运行的时候会创建全局上下文对象,该对象中有一个VO变量对象保存着value,执行的时候赋值为2019。然后是fn()函数执行时创建全局上下文对象,同时创建变量作用域链,链表第一个作用域为当前作用域,第二个作用域为全局作用域,另外该对象也有一个VO变量对象首先初始化一个value变量,值为undefined,执行的时候第一句console.log首先执行,此时从当前作用域中找到value,值为undefined,执行第二句则将value赋值为一个对象,所以执行第三句就会从当前作用域中找到value对象。Fn函数外部的console.log只能从全局作用域中找到value值为2019。
变量提升面试题案例二:
if(!("value" in window)){
var value = 2019;
}
console.log(value); // 输出什么?
首先in是用来判断value属性是否在window对象中,问输出的value值是什么?依然是根据执行上下文的运行机制,value在上下文创建的时候会首先被创建在VO对象中(在全局上下文中VO和this都是window对象),赋值为undefined,等到执行的时候VO变成AO(激活对象),这个时候才会对变量进行实际赋值。那么程序执行的时候判断value已经在window中了,这个if语句就不会被执行,这样输出就是undefined了。
变量提升面试题案例三:
console.log(fn);
var fn = 2019;
console.log(fn);
function fn(){}
问以上代码会输出什么?同样是根据执行上下文的机制,全局执行上下文创建的时候,会将函数fn()首先提前在VO对象中创建,并赋值为函数的引用,后处理fn变量,但是此时会直接跳过fn变量,因为防止同名变量覆盖同名的函数。等到全局上下文入栈执行的时候,第一个输出首先输出的是fn函数,执行第二句会将fn函数覆盖掉,变量fn变量并赋值为2019,那么第二个输出就为2019了。
变量提升面试题案例四:
fn();
console.log(v1);
console.log(v2);
console.log(v3);
function fn(){
var v1 = v2 = v3 = 2019;
console.log(v1);
console.log(v2);
console.log(v3);
}
这个案例主要注意的是var v1=v2=v3这句的变量声明,因为v2和v3没有使用var声明,所以这两个变量属于全局作用域的变量,而v1使用var声明则为fn函数作用域的变量,所以第四个输出出错,其它都是输出2019。
变量提升面试题案例五:
function fn(){
for(var i = 0;i < 10;i++){
console.log(i);
}
console.log(i);
}
fn();
分析这个案例第一个要注意的是,JavaScript是没有块作用域的,也就是说for循环块声明的变量在外部都可以使用,所以最后一个console.log输出一定不会出错。而循环体内,i的输出很明显是0-9了,那么最后一个输出是多少呢?这个跟理解for循环语句有关,我们分析最后一个i,即i=9的时候,输出9,然后加1,即i=10,再判断是否小于10,不小于,那么跳出循环体,所以最后一个输出为10。
以上就是关于JavaScript面试题中的变量提升题目的分析,它主要涉及到基本的执行上下文原理,学会这个可以让你更好编写和调试JS程序。
评论前必须登录!
注册