提高是一種將變量和函數的聲明移到函數做用域(若是不在任何函數內的話就是全局做用域)最頂部的機制。javascript
提高影響了變量的生命週期,一個變量的生命週期包含3個階段:java
聲明——建立一個新變量,例如var myValue;函數
初始化——用一個值初始化變量,例如myValue=150;spa
使用——使用變量的值,例如alert(myValue)。code
javascript並無嚴格遵循這個順序,所以提供了更多的靈活性。好比:函數的使用能夠在聲明以前。blog
這是由於javascript的函數聲明會被提高到做用域頂部。生命週期
變量提高在不一樣方面的影響也不一樣:ip
變量聲明:使用var ,let ,const關鍵字作用域
函數聲明:使用function(){......}語法io
類聲明:使用class關鍵字
函數聲明在函數做用域內建立並初始化一個變量。默認狀況下,聲明可是未初始化的變量的值是undefined。
1.提高var:使用var聲明的變量會被提高到所在函數做用域的頂部,若是在聲明以前訪問該變量,它的值會是undefined。雖然它的聲明提高了,可是它的賦值沒有提高到函數做用域頂部,依然留在原地。
function sum(a,b){ var myString; //提高到頂部 console.log(myString); //undefined myString="HelloWorld"; //賦值不受影響 console.log(myStriing); //‘HelloWorld’ return a+b; }
2.塊級做用域變量:let
let聲明在塊級做用域內建立並初始化一個變量:默認狀況下,聲明可是未初始化的變量的值是undefined。
let是ECMAScript6引入的一個巨大的改進,它容許代碼在代碼塊的級別上保持模塊性和封裝性;
使用let定義的變量會被提高到代碼塊的頂部。可是若是在聲明前訪問該變量,javascript會拋出異常ReferenceError:is not defined。
在聲明語句一直到代碼庫的頂部,變量都好像在一個臨時死亡區間中同樣,不能被訪問。
function isTruthy(value){ var myVariable='Value 1'; console.log(myVariable); //Value1 if(value){ console.log(myVariable); //ReferenceError:myVariable is not defined,臨時死亡區 let myVariable='Value 2'; console.log(myVariable); //Value 2 return true; } }
以上代碼能夠確認let變量確實被提高了。
let在塊級做用域內提高保護了變量不受外層做用域影響。先聲明,後使用。
3.常量const
常量聲明在塊級做用域內建立並初始化一個常量:當聲明一個變量時,必須在同一條語句中對該變量進行初始化。在聲明與初始化以後,變量的值不能被修改。
使用const定義的常量會被提高到代碼塊的頂部。因爲存在臨時死亡區間,常量在聲明以前不能被訪問。常量提高效果與let聲明變量的效果相同。
4.函數聲明:函數聲明使用提供的名稱和參數建立一個函數
函數聲明的提高容許你在所屬做用域內任何地方使用該函數,即便在聲明以前也能夠。函數能夠在當前做用域或子做用域內的任何地方訪問。
注意:函數聲明function(){....}和函數表達式var=function(){.....}之間的區別
5.類聲明
類聲明會被提高到塊級做用域的頂部。可是若是你在聲明前使用類,javascript會拋出異常。先聲明類,而後建立實例。與let的提高效果相似。