第七颗皮蛋
新手
新手
  • 最后登录2019-06-14
  • 发帖数7
阅读:7208回复:1

一道面试题:关于函数的提升中会出现的BUG。

楼主#
更多 发布于:2019-02-22 12:18
昨天我朋友去顶呱呱面试,其中有几道面试题非常有意思,分享一下。

题(顶呱呱web-前端中级,薪资13K):以下代码会输出什么结果。


a(); //console.log(a);
if(true){
function a(){
        console.log('第一个A'); }

function b(){
        console.log('第一个B'); }
}else{ function a(){
        console.log('第二个A'); }

function b(){
        console.log('第二个B'); }
} b();


题目分析:
我们知道JS中存在变量提升,普通变量声明会提升到作用域顶部(限使用var 声明变量,只存在函数作用域),函数会将值一起提升到作用域顶部。即:
fn();
function fn(){

}

函数会执行,因为fn整个函数会提升到顶部。如有一下代码:
fn();
function fn(){
    console.log('1111');
}
function fn(){
    consloe.log('2222');
}
会打印 2222 因为两个函数都会提升,第二个 fn 提升后会覆盖第一个 fn 的值。


由以上分析,我们可以得出原面试题中答案因该为:‘ 第二个A ’ 和 ‘ 第二个B ’。


但是当我们在浏览器中执行面试题代码时会发现,在目前版本的 chorme、火狐、IE 都会报错,提示a并不是一个函数:


图片:微信图片_20190222113530.png


我们将a();注销,并在这个位子打印a:

//a(); console.log(a);
if(true){
function a(){
        console.log('第一个A'); }

function b(){
        console.log('第一个B'); }
}else{ function a(){
        console.log('第二个A'); }

function b(){
        console.log('第二个B'); }
} b();

结果为 :

图片:微信图片_20190222115647.png



用IE10测试后结果为:


图片:微信图片_20190222115956.png



现在就非常有趣了,按照我们之前的分析,因为a(),和b()都是写在if条件里面的,虽然有块级包裹,但并不构成作用域,所以答案应该为IE的结果,但是分析上面chorme,和火狐的结果可以发现函数名提升了,但是函数的值并没有提升,为了规避if判断的影响,测试了以下代码:

console.log(f);
f();
do{
function f() {
        console.log('fff'); }
}while (false);

chrome结果:

图片:微信图片_20190222120722.png



以上代码,应该是都会执行的,但是可见执行到f()时,代码已经报错,提示f不是一个函数,但是f能够被打印出undefined,说明变量f存在。

得出以下结论:
目前新版本的chrome,火狐,IE(11)中,使用 function  f(){}声明函数时,如果函数声明在块级域中,JS会自动将代码修正为 var f = function(){},因此只有f变量名提升,后面的函数值并没有提升。


经查看书籍得出,在低版本浏览器中chrome,火狐,IE也会对其进行不同的处理,火狐会按照提升变量名的方式处理,chrome,和IE会按照提升函数整体处理。


以上为个人测试结果,如有错还望指出。

最新喜欢:

doubleyongdouble...
doubleyong
管理员
管理员
  • 最后登录2026-05-25
  • 发帖数1198
  • 最爱沙发
  • 喜欢达人
  • 原创写手
  • 社区居民
  • 忠实会员
沙发#
发布于:2019-02-22 12:50
知识需要管理,知识需要分享
游客


返回顶部

公众号

公众号