一道js變量上浮面試題

function a() {
   var a = 1;
   function b() {
     a = 10;
      return;
      function a() {}
    }
    b();
    log(a); 
}
a(); 

輸出結果(下一行,拖動或ctrl+A)

■■■■■■■   輸出:   1    ■■■■■■■

 

 

  

 

解析:

昨天去面試,就掉到上浮的坑裏,本來是知道這個問題的,但是不太熟練又被迷惑。

最後面試官給我說,變量上浮,是在定義的時候產生的,執行時不存在這個問題。

 

 

來看這個題,a()函數 可以重新這樣寫

function a(){

  function b()//上浮
    {

    function a(){};//上浮至最高,變量a是函數

    a=10;//變量a又被賦值爲10

    return;

    }

  var a;
  
  a=1;
  b();
//執行b(),因爲b上浮到頂部,所以先執行了b()中的a=10,然後才執行了上一行的a=1,所以最終結果是1   log(a);   } a();

 

 

_______________________________________________________

(分割線,在這個題的基礎上修改一下)

function test() {
    //a()
      return console.log(a,b);
      function a(){console.log(test)}
      var b = 'ssss';
    }
test();

這個裏面函數a()和變量b的定義都是在return之後,輸出結果是什麼?

如果把a()的註釋去掉,會得到什麼?

 

輸出結果: function a()內容和undefined

這說明,在函數執行前(或者說函數執行時),function a()形式的聲明,可以提升至作用域頂部,而var就不具備這個作用。

如果把註釋去掉,執行a(),則會報錯test未定義,說明函數只有在執行時纔會檢查調用的變量是否存在,可以推想,未執行的函數內部如果有錯誤也是不會報錯的,請看下面這個代碼:

function b(){
    asdfasdfasdf
    as
    dfa
    sdf
    asdfasdfasdffas
    dfa
}

不執行b(),是不會出現任何錯誤的。

 

再看一段代碼:

function a() {
   var a = 1;
   function b() {
     console.log(a);
     a = 10;
     console.log(a);
      return;
      function a() {a=5;}
    }
    b();
    console.log(a); 
}

a(); 

 

輸出:

function a()

10

1

這是因爲return後面的function a()提升至頂部,並在當前函數作用域內聲明瞭一個本地局域變量a,a=10賦值給該局域變量。

 

如果把return後面的function a()註釋掉,則輸出

1

10

10

這兩種輸出說明,function a()具有和var a同樣的作用,指定了a的作用域爲函數體內。修改一下,比如:

function a() {
   var a = 1;
   function b() {
     console.log(a)
     var a  = 10;
     console.log(a)
      return;
    }
    b();
    console.log(a); 
}

a(); 

 

這裏b()函數體內的var a=10將變量a的作用域設定在函數體內,a=10的賦值就會在b函數內執行,而不會達到外部的a()函數。等價於:

function a() {
   var a = 1;
   function b() {
    var a;
     console.log(a)
     a  = 10;
     console.log(a)
      return;
    }
    b();
    console.log(a); 
}

a(); 

 

 

好了,看明白上面的內容,再來看餐後甜點:

var foo = 1;

    function Main(){
        console.log(foo);
        var foo = 2;
        console.log(this.foo);
        this.foo = 1;
    }

Main();
new Main();

輸出有什麼不同? 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章