摘要:變量提升需要注意兩點提升的部分只是變量聲明,賦值語句和可執(zhí)行的代碼邏輯還保持在原地不動提升只是將變量聲明提升到變量所在的變量范圍的頂端,并不是提升到全局范圍,說明如下會輸出變量提升之后的效果函數(shù)聲明會提升,但是函數(shù)表達式就不了。
問題
有些朋友可能會覺得javascript的代碼是從上到下,一行一行的解釋執(zhí)行的。如果按照這樣的思路,在有些情況下閱讀代碼會得到錯誤的結果,考慮以下代碼:
a = 2; var a; console.log(a);
console.log(a)應該輸出什么呢?有些開發(fā)者覺得會輸出undefined,因為var a在"a = 2"之后,變量a被重復定義了,但是沒有被賦值,所以是"undefined"。但是結果輸出是2。如下圖所示:
我們再來考慮另一段代碼,如下所示:
console.log(a); var a = 2;
這段代碼會輸出什么樣的結果呢?有些人可能會覺得輸出ReferenceError。因為變量a在沒有聲明的情況下就被使用了。真實結果呢,如下圖所示:輸出的是undefined
為什么會這樣呢?這就牽出了本文的主題:JavaScript聲明提升
JavaScript代碼的運行規(guī)則在JavaScript代碼運行之前其實是有一個編譯階段的。編譯之后才是從上到下,一行一行解釋執(zhí)行。變量提升就發(fā)生在編譯階段,它把變量和函數(shù)的聲明提升至作用域的頂端。(編譯階段的工作之一就是將變量與其作用域進行關聯(lián))。
所以對于代碼var a =2;來說,編譯器看到的是兩行代碼var a; a = 2;第一個語句是聲明語句,在編譯階段處理。第二個語句是賦值語句,在運行階段處理。
那么我們再回過頭來看看問題中出現(xiàn)的代碼:
a = 2; var a; console.log(a);
應該這樣來處理:
var a; //編譯階段 a = 2; //運行階段 console.log(a); //運行階段
所以這段代碼的最終輸出的結果是2。
第二段代碼:
console.log(a); var a = 2;
應該這樣來處理:
var a; //編譯階段 console.log(a); //運行階段 a = 2; //運行階段
所以這段代碼的最終輸出結果是undefined。
變量提升需要注意兩點:
提升的部分只是變量聲明,賦值語句和可執(zhí)行的代碼邏輯還保持在原地不動
提升只是將變量聲明提升到變量所在的變量范圍的頂端,并不是提升到全局范圍,說明如下:
foo(); function foo(){ console.log(a); //會輸出undefined var a = "2"; } //變量提升之后的效果 function foo(){ var a; console.log(a); a = "2"; } foo();
函數(shù)聲明會提升,但是函數(shù)表達式就不了。看如下代碼:
foo(); var foo = function bar(){ //這是一個函數(shù)表達式,不再是函數(shù)聲明。 console.log("bar"); }
處理方式如下:
var foo; foo(); //TypeError,因為還沒有賦值 bar(); //bar不可以在全局范圍內引用 foo = function bar(){ console.log("bar"); }函數(shù)是一等公民
變量聲明和函數(shù)聲明都會得到變量提升,但函數(shù)聲明會最先得到提升,然后是變量聲明。
考慮如下代碼:
foo(); //輸出的結果為1 var foo; function foo(){ console.log(1); } foo = function(){ console.log(2); }
處理方式如下:
function foo(){ console.log(1); } foo(); foo = function(){ console.log(2); }
注意:var foo;由于是重復聲明變量,所以被編譯優(yōu)化去掉。
最后再來說明幾種情況對于函數(shù)聲明來說,如果定義了相同的函數(shù)變量聲明,后定義的聲明會覆蓋掉先前的聲明,看如下代碼:
foo(); //輸出3 function foo(){ console.log(1); } var foo = function(){ console.log(2); } function foo(){ console.log(3); }
JavaScript中是沒有塊級作用域的概念(ps:ES6中有改進了),看如下代碼:
foo(); //輸出結果為2 var a = true; if(a){ function foo(){ console.log(1); } }else{ function foo(){ console.log(2); } }
這段代碼輸出結果為2,if語句沒有塊級作用域的功能,所以函數(shù)聲明都被提升到全局作用域中,又因為定義了兩個foo,后來的定義覆蓋了前邊的定義,所以輸出結果為2。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86101.html
摘要:變量提升什么是變量提升在函數(shù)體內聲明的變量,無論你是在函數(shù)的最底端還是中間聲明的,那么都會把該變量的聲明提升到函數(shù)的最頂端相當于第一行,但是只是提升變量的聲明,不會賦值。 1、變量提升 什么是變量提升?在函數(shù)體內聲明的變量,無論你是在函數(shù)的最底端還是中間聲明的,那么都會把該變量的聲明提升到函數(shù)的最頂端(相當于第一行),但是只是提升變量的聲明,不會賦值。 var num = 10; fu...
摘要:發(fā)布自的博客,歡迎大家轉載,但是要注意注明出處。另外,該文章收納在的個人的知識整理倉庫,歡迎投稿介紹變量提升是人們對執(zhí)行上下文工作方式的一種認識,并不是官方給出的改變從字面上理解,變量提升的意思是變量和函數(shù)的聲明會在物理層移動到作用域的最前 發(fā)布自Kindem的博客,歡迎大家轉載,但是要注意注明出處。另外,該文章收納在Kindem的個人的 IT 知識整理倉庫,歡迎 Star、Fork、...
摘要:不同的是函數(shù)體并不會再被提升至函數(shù)作用域頭部,而僅會被提升到塊級作用域頭部避免全局變量在計算機編程中,全局變量指的是在所有作用域中都能訪問的變量。 ES6 變量作用域與提升:變量的生命周期詳解從屬于筆者的現(xiàn)代 JavaScript 開發(fā):語法基礎與實踐技巧系列文章。本文詳細討論了 JavaScript 中作用域、執(zhí)行上下文、不同作用域下變量提升與函數(shù)提升的表現(xiàn)、頂層對象以及如何避免創(chuàng)建...
摘要:輸出的結果為輸出的結果為提升后輸出的結果為重新定義了變量輸出的結果為如果定義了相同的函數(shù)變量聲明,后定義的聲明會覆蓋掉先前的聲明,看如下代碼輸出練習的值是多少的值是多少第二題的解析請看這里參考資料文章文章中文版鏈接文章推薦文章變量提升 JavaScript 變量聲明提升 原文鏈接 一個小例子 先來看個例子: console.log(a); // undefined var a =...
摘要:但是碰到聲明提升,這種想法就會被打破。聲明一個函數(shù)進行相應的操作,會得到函數(shù)聲明提升的結果。由此可以發(fā)現(xiàn)變量和函數(shù)的聲明都會被提升在其他代碼的前面執(zhí)行。一個普通塊內部的函數(shù)聲明通常會被提升到所在的作用域的頂部。的創(chuàng)建初始化和賦值均會被提升。 Javascript聲明提升 在分析聲明提升之前,我認為有必要知道的兩點: 一、引擎查詢變量的兩種方式 引擎查詢變量的方式可以分為LHS和RHS兩...
閱讀 2624·2021-11-12 10:36
閱讀 2262·2021-08-23 09:47
閱讀 1683·2019-08-30 15:44
閱讀 1405·2019-08-30 14:10
閱讀 2246·2019-08-29 16:52
閱讀 2339·2019-08-29 16:40
閱讀 1590·2019-08-29 16:17
閱讀 2412·2019-08-26 13:21