js變量提升


javascript中ES5的var、function,ES6的function *、let、const、class會被提升,但是var、function、function *和let、const、class的的提升並不相同。

本文只討論ES5中變量提升,ES6中變量提升

ES5變量提升

首先了解js的執行環境和作用域

執行環境

執行環境定義了變量和函數有權訪問的其他數據,決定了他們各自的行為。每個執行環境都有與之對應的變量對象(variable object),此對象保存着環境中定義的所有變量和函數。我們無法通過代碼來訪問變量對象,但是解析器在處理數據時會在后台使用到它。

 -全局執行環境

  全局執行環境是最外圍的一個執行環境,根據ECMAscript實現所在的宿主環境不同,表示執行環境的對象也不同。在web瀏覽器中,我們可以認為它是window對象,因此所有的全局變量和函數都是作為window對象的屬性和方法創建的。代碼載入瀏覽器時,全局環境被創建,應用程序退出,如關閉網頁或者瀏覽器時,全局執行環境被銷毀。

 -函數執行環境

  每個函數都有自己的執行環境,當執行流進入一個函數時,函數的環境就被推入一個環境棧中,當函數執行完畢后,棧將其環境彈出,把控制權返回給之前的執行環境。

作用域

在ES5中,js只有兩種形式的作用域:全局作用域和函數作用域。

 -全局作用域

  全局對象的作用域,任意地方都可以訪問到(如果沒有被函數作用域覆蓋)。在ES6中,新增了一個塊級作用域(最近的大括號涵蓋的范圍),但是僅限於let方式申明的變量。

 -函數作用域

  整個函數范圍

作用域鏈

 

變量提升(hoisting)

 ES5 提升有變量提升和函數提升。

 原則: 

     1、所有申明都會被提升到作用域的最頂上;

     2、同一個變量申明只進行一次,並且因此其他申明都會被忽略;

     3、函數聲明的優先級優於變量申明,且函數聲明會連帶定義一起被提升。

 -變量提升

 把變量聲明提升到函數的頂部,但是變量賦值不會提升。

console.log(a);
var a = 10;
//輸出為undefined
/************/
var a;
console.log(a);
a = 10;
//與上例等價

 

function add(){
    y = 10;
    var y = 1;
    console.log(y); 
}
add(); //輸出1

注意:變量未聲明,直接使用,輸出‘變量 is not defined’。

   

 -函數提升

  函數提升會將函數聲明連帶定義一起提升。

  在JavaScript中函數的創建方式有三種:函數聲明、函數表達式(函數字面量)、函數構造法(動態的,匿名的)。只有函數聲明創建的函數會執行函數提升,字面量定義的函數(實質為變量+匿名函數)會執行變量提升。

 test1(); 
 function test1(){ 
     console.log("可以被提升"); 
 } 

 test2(); 
 var test2 = function(){ 
     console.log("不可以被提升"); 
 } 

console.log(test2); 
var test2 = function(){ 
   console.log("不可以被提升"); 
}   

函數和變量同時提升

console.log(test3);
function test3(){console.log('func');}
var test3 = 'Mary';

 

  

 

 

 

  

 

  

 

  


免責聲明!

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



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