這篇文章帶給大家的內容是關於js中變數宣告以及函數宣告提升的詳細解析(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
變數宣告提升
1、變數定義
可以使用var定義變量,變數如果沒有賦值,那麼變數的初始值為undefined。
2、變數作用域
變數作用域指變數起作用的範圍。變數分為全域變數和局部變數。全域變數在全域都擁有定義;而局部變數只能在函數內有效。
在函數體內,同名的局部變數或參數的優先權會高於全域變數。也就是說,如果函數內存在和全域變數同名的局部變數或參數,那麼全域變數將會被局部變數覆蓋。
所有不使用var定義的變數都視為全域變數
3、函數作用域和宣告提前
JavaScript的函數作用是指在函數內宣告的所有變數在函數體內總是有定義的,也就是說變數在宣告之前已經可用,所有這特性稱為宣告提前(hoisting),即JavaScript函數裡的所有宣告(只是聲明,但不涉及賦值)都被提前到函數體的頂部,而變數賦值操作留在原來的位置。如下列範例:
註解:宣告事先是在JavaScript引擎的預編譯時進行,是在程式碼開始運作之前。
var scope = 'global';function f(){ console.log(scope); var scope = 'local'; console.log(scope); }
由於函數內宣告提升,所以上面的程式碼其實是這樣的
var scope = 'global';function f(){ var scope; //变量声明提升到函数顶部 console.log(scope); scope = 'local'; //变量初始化依然保留在原来的位置 console.log(scope); }
經過這樣變形之後,答案就非常明顯了。由於scope在第一個console.log(scope)語句之前就已經定義了,但是並沒有賦值,因此此時scope的指是undefined.第二個console.log(scope)語句之前,scope已經完成賦值為'local',所以輸出的結果是local。
函數宣告提升
函數宣告語法
f('superman');function f(name){ console.log(name); }
函數表達式語法
f('superman');var f= function(name){ console.log(name); }
執行上面的程式碼,會報錯Uncaught ReferenceError: f is not defined(…),錯誤訊息顯示說f沒有被定義。
為什麼同樣的程式碼,函數宣告和函數表達式有差異呢?
這是因為,函數宣告有一個非常重要的特徵:函數宣告提升,函數宣告語句將會被提升到外在腳本或是外在函數作用域的頂端(是不是跟變數提升非常類似)。正是因為這個特徵,所以可以把函數宣告放在呼叫它的語句後面。如下面例子,最終的輸出結果應該是什麼? :
var getName = function(){ console.log(2); }function getName (){ console.log(1); } getName();
可能會有人覺得最後輸出的結果是1。讓我們來分析一下,這個例子涉及了變數宣告提升和函數宣告提升。如同前面說到的函數宣告提升,函數宣告function getName(){}的宣告會被提前到頂端。而函數表達式var getName = function(){}則表現出變數宣告提升。因此在這種情況下,getName也是一個變量,因此這個變數的宣告也會提升到底部,而變數的賦值仍然保留在原來的位置。要注意的是,函數優先,雖然函數宣告和變數宣告都會被提升,但是函數會先被提升,然後才是變數。因此上面的函數可以轉換成下面的樣子:
function getName(){ //函数声明提升到顶部 console.log(1); } var getName; //变量声明提升 getName = function(){ //变量赋值依然保留在原来的位置 console.log(2); } getName(); // 最终输出:2
所以最終的輸出結果是:2。在原來的例子中,函數宣告雖然是在函數表達式後面,但由於函數宣告提升到頂部,因此後面getName又被函數表達式的賦值運算給覆寫了,所以輸出2。
相關推薦:
以上是js中變數宣告以及函數宣告提升的詳細解析(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!