js提升機制(hoisting)


這是我申請博客園寫的第一篇文章,想把這兩天學習的關於js的變量和函數提升機制(hoisting)記錄下來。

從網上看到這么一段代碼:

 var c = 2;

 function c(){

  c = 22;

  console.log("c="+c);

 }

 c();//會報錯,變量提升機制導致的(c is not a function)

問運行結果是什么,然后不假思索的就以為是22,因為c=22這行看起來就是對外面的全局變量c重新定義了

但是實際上不是的,這句話不會執行到c()的時候會報錯(number is not a function),有點蒙蔽,這是怎么了,查了好久,才知道js有個提升機制,變量和函數(函數聲明的方式有提升機制,函數表達式沒有這個機制)都有提升機制,而且函數提升機制的優先級高於變量的,這也就是說當函數名和變量名相同的時候,拿上面這個例子來說,c被提升到代碼最前端,並且被賦值為一個函數,然后才會 被賦值為2,上面的代碼等效於下面這個:

var c = function c(){

  c = 22;

  console.log("c="+c);

};

c = 2;

c();

執行的時候,c先被賦值為一個函數,然后緊接着又被賦值為數字2,這樣在這句賦值語句下面執行c()的時候,c就不是函數了,而是數字,如果在c = 2;這句話的上面執行c()的話,就沒有問題了,結果是c = 22;

 

再來看另一個問題,函數聲明和函數表達式有什么不同,就是下面這兩種情況:

d();//1

function d(){//方式1

  alert("1");

}

 

d();//undefined is not a function

var d = function(){//方式2

  alert("1");

};

這兩種聲明函數方式不同之一在於:

方式1可以在d聲明之前使用d()來調用函數,方式2卻不可以

 

這個也是可以用變量提升機制來解釋的,方式1的寫法和下面這個等價:

var d = function d(){

  alert("1");

};

d();

所以執行沒有問題,但是第二種寫法的函數就沒有變量提升機制,好像也可以用這個方式來解釋,第二種寫法等價於下面這樣:

var d;

d();

d = function(){

  alert("1")

};

這樣的話,執行d()的時候,d還沒有被定義為函數,只是被聲明了,所以會執行報錯。(這樣應該可以解釋的通,不對的地方,請務必讓我知道)

 

來看個復雜點的例子:

var a = 1;

function b() {        //變量提升機制:如這個例子所示,執行b()時

  console.log(a);   // function a(){}

  a = 10; //這可不是對外面的全局變量a定義哦

  console.log(a); //10(局部變量)

  var a = 11;

  console.log(a); //11(局部變量)

  return;

  function a(){

    alert("abc");

  }

}

b();

console.log(a); //1(全局變量) 

 

上面的例子等價於下面這樣:

var b = function b(){

  var a = function a(){

    alert("abc");

  }

  console.log(a);

  a = 10;

  console.log(a);

  a = 11;

  console.log(a);

  return;

}

var a;

a = 1;

b();

console.log(a);

 

不知道寫的這點東西對大家有沒有一點幫助呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM