您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么理解JavaScript中的變量、范圍和提升”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
變量是許多編程語言的基本組成部分,也是新手需要學習的第一個也是最重要的概念。JavaScript中有許多不同的變量屬性,以及命名變量時必須遵循的一些規則。在JavaScript中,有三個關鍵字用于聲明變量——var、let和const——每個關鍵字都會影響代碼對變量的不同解釋。
本教程將介紹什么是變量,如何聲明和命名變量,并進一步研究var、let和const之間的區別。我們還將回顧提升的影響以及全局和局部作用域對變量行為的重要性。
理解變量
變量是用于存儲值的命名容器。我們可能多次引用的一條信息可以存儲在一個變量中,供以后使用或修改。在JavaScript中,變量中包含的值可以是任何JavaScript數據類型,包括數字、字符串或對象。
在今天的JavaScript所基于的ECMAScript 2015 (ES6)語言規范之前,只有一種方法來聲明變量——使用var關鍵字。因此,大多數較老的代碼和學習資源將只對變量使用var。我們將在下面單獨一節討論var、let和const關鍵字之間的區別。
我們可以使用var來演示變量本身的概念。在下面的示例中,我們將聲明一個變量,并為其賦值。
// Assign the string value Sammy to the username identifiervar username = "sammy_shark";
本聲明由以下幾部分組成:
使用var關鍵字聲明變量
變量名(或標識符),用戶名
賦值操作,由=語法表示
分配的值“sammy_shark”
現在我們可以在代碼中使用username。JavaScript將記住username表示字符串值sammy_shark。
// Check if variable is equal to valueif (username === "sammy_shark") { console.log(true); }
輸出:
true
如前所述,變量可以用來表示任何JavaScript數據類型。在本例中,我們將使用字符串、數字、對象、布爾值和null值聲明變量。
// Assignment of various variablesvar name = "Sammy";var spartans = 300;var kingdoms = [ "mammals", "birds", "fish" ];var poem = { roses: "red", violets: "blue" }; var success = true;var nothing = null;
使用console.log,我們可以看到特定變量中包含的值。
// Send spartans variable to the consoleconsole.log(spartans);
輸出:300
變量將數據存儲在內存中,稍后可以訪問和修改這些數據。變量也可以重新分配,并給定一個新值。下面的簡化示例演示了如何將密碼存儲到變量中,然后進行更新。
//為password變量賦值var password = "hunter2";//用一個新值重新分配變量值password = "hunter3";console.log(password);
輸出:
'hunter3'
在實際的程序中,密碼很可能安全地存儲在數據庫中。然而,這個例子說明了一種情況,在這種情況下,我們可能需要更新變量的值。password的值是hunter2,但是我們將其重新分配給了hunter3,這是JavaScript從那時起可以識別的值。
命名變量
變量名在JavaScript中稱為標識符。我們討論了在理解JavaScript語法和代碼結構時命名標識符的一些規則,總結如下:
變量名只能由字母(a-z)、數字(0-9)、美元符號($)和下劃線(_)組成
變量名不能包含任何空白字符(制表符或空格)
數字不能是任何變量的名稱開頭
保留的關鍵字不能用作變量的名稱
變量名區分大小寫
JavaScript還習慣在使用var或let聲明的函數和變量的名稱中使用駝峰大小寫(有時作為駝峰大小寫進行樣式化)。這是一種將第一個單詞小寫,然后將后面每個單詞的第一個字母大寫,中間沒有空格的做法。除了一些例外,大多數非常量的變量都遵循這種約定。使用const關鍵字聲明的常量變量的名稱通常都是大寫的。
這可能看起來像要學習很多規則,但很快就會成為編寫有效和常規變量名稱的第二天性。
var、let和const之間的區別
JavaScript有三個不同的關鍵字來聲明變量,這給語言增加了額外的復雜性。三者之間的區別是基于范圍、提升和重新分配。
var功能范圍YesYesYeslet阻止范圍NoYesNoconst阻止范圍NoNoNo
您可能想知道應該在自己的程序中使用這三種方法中的哪一種。一個普遍接受的做法是盡可能多地使用const,并在循環和重新分配的情況下使用let。通常,在處理遺留代碼之外可以避免var。
變量作用域
JavaScript中的作用域是指代碼的當前上下文,它決定了變量對JavaScript的可訪問性。范圍的兩種類型是局部的和全局的:
全局變量是在塊之外聲明的變量
局部變量是在塊內聲明的變量
在下面的示例中,我們將創建一個全局變量。
//初始化一個全局變量var creature = "wolf";
我們知道變量可以重新分配。使用局部作用域,我們實際上可以創建與外部作用域中的變量同名的新變量,而無需更改或重新分配原始值。
在下面的示例中,我們將創建一個全局species變量。函數內部是一個具有相同名稱的局部變量。通過將它們發送到控制臺,我們可以看到變量的值如何根據范圍而不同,并且原始值不會更改。
//初始化一個全局變量var species = "human";function transform() {//初始化一個局部的、函數作用域的變量 var species = "werewolf"; console.log(species);}//記錄全局和局部變量console.log(species);transform();console.log(species);
輸出:
humanwerewolfhuman
在本例中,局部變量是函數作用域的。使用var關鍵字聲明的變量總是函數作用域,這意味著它們將函數識別為具有獨立作用域。因此,這個局部作用域的變量不能從全局作用域訪問。
然而,新的關鍵字let和const是塊范圍的。這意味著從任何類型的塊(包括函數塊、if語句、for和while循環)創建一個新的本地范圍。
為了說明函數作用域變量和塊作用域變量之間的區別,我們將使用let在if塊中分配一個新變量。
var fullMoon = true;//初始化一個全局變量let species = "human";if (fullMoon) { //初始化一個塊范圍的變量 let species = "werewolf"; console.log(`It is a full moon. Lupin is currently a ${species}.`);}console.log(`It is not a full moon. Lupin is currently a ${species}.`);
輸出:
It is a full moon. Lupin is currently a werewolf.It is not a full moon. Lupin is currently a human.
在此示例中,species變量具有一個值global(human),另一個值local(werewolf)。var但是,如果我們使用,則會有不同的結果。
//使用var初始化一個變量var species = "human";if (fullMoon) { //嘗試在一個塊中創建一個新變量 var species = "werewolf"; console.log(`It is a full moon. Lupin is currently a ${species}.`);}console.log(`It is not a full moon. Lupin is currently a ${species}.`);
輸出:
It is a full moon. Lupin is currently a werewolf.It is not a full moon. Lupin is currently a werewolf.
在這個例子的結果中,全局變量和塊范圍的變量都以相同的值結束。這是因為您不是使用var創建一個新的本地變量,而是在相同的范圍內重新分配相同的變量。var不能識別是否屬于不同的新范圍。通常建議聲明塊范圍的變量,因為它們生成的代碼不太可能無意中覆蓋變量值。
變量提升
到目前為止,在大多數示例中,我們已經使用var聲明了一個變量,并使用一個值初始化了它。在聲明和初始化之后,我們可以訪問或重新分配變量。
如果我們試圖在變量被聲明和初始化之前使用它,它將返回undefined。
//在聲明變量之前嘗試使用它console.log(x);/ /變量賦值var x = 100;
輸出:
undefined
但是,如果省略var關鍵字,就不再聲明變量,而是初始化它。它將返回一個ReferenceError并停止腳本的執行。
//在聲明變量之前嘗試使用它console.log(x);//沒有var的變量賦值x = 100;
輸出:
ReferenceError: x is not defined
原因在于提升,這是JavaScript的一種行為,其中變量和函數聲明被移到它們作用域的頂部。由于只掛起實際聲明,而沒有初始化,因此第一個示例中的值返回未定義的值。
為了更清楚地演示這個概念,下面是我們編寫的代碼以及JavaScript如何解釋它。
// The code we wroteconsole.log(x);var x = 100;// How JavaScript interpreted itvar x;console.log(x);x = 100;
JavaScript在執行腳本之前將x保存為內存作為變量。 由于它在定義之前仍然被調用,因此結果是未定義的而不是100.但是,它不會導致ReferenceError并停止腳本。
盡管var關鍵字實際上并未更改var的位置,但這有助于表示提升的工作原理。 但是,這種行為可能會導致問題,因為編寫此代碼的程序員可能希望x的輸出為true,而不是undefined。
在下一個例子中,我們還可以看到提升是如何導致不可預測的結果的:
//在全局范圍內初始化xvar x = 100;function hoist() {//不應影響編碼結果的條件 if (false) { var x = 200; } console.log(x);}hoist();
輸出:
undefined
在本例中,我們聲明x全局為100。根據if語句,x可以更改為200,但是由于條件為false,所以它不應該影響x的值。
這種不可預測的行為可能會在程序中引起bug。由于let和const是塊范圍的,所以它們不會以這種方式提升,如下所示。
//在全局范圍內初始化xlet x = true;function hoist() {//在函數作用域中初始化x if (3 === 4) { let x = false; } console.log(x);}hoist();
輸出:
true
變量的重復聲明(這在var中是可能的)將在let和const中拋出一個錯誤。
//試圖覆蓋用var聲明的變量var x = 1;var x = 2;console.log(x);
輸出:2
//試圖覆蓋用let聲明的變量let y = 1;let y = 2;console.log(y);
輸出:
Uncaught SyntaxError: Identifier 'y' has already been declared
總之,使用var引入的變量有可能受到提升的影響,提升是JavaScript中的一種機制,其中變量聲明被保存到內存中。這可能導致代碼中出現未定義的變量。let和const的引入解決了這個問題,它在試圖在聲明變量之前使用該變量或多次聲明該變量時拋出一個錯誤。
常量
許多編程語言都有常量,這些常量是不能修改或更改的值。在JavaScript中,const標識符是根據常量建模的,不能重新分配分配給const的值。
將所有const標識符都寫成大寫是常見的約定。這將它們與其他變量值區分開來。
在下面的示例中,我們使用const關鍵字將變量SPECIES初始化為常量。試圖重新分配變量將導致錯誤。
//給const賦值const SPECIES = "human"; //嘗試重新分配值SPECIES = "werewolf";console.log(SPECIES);
輸出:
Uncaught TypeError: Assignment to constant variable.
因為不能重新分配const值,所以需要同時聲明和初始化它們,否則也會拋出錯誤。
//聲明,但不初始化constconst TODO;console.log(TODO);
輸出:
Uncaught SyntaxError: Missing initializer in const declaration
不能在編程中更改的值稱為不可變值,而可以更改的值是可變的。雖然const值不能重新分配,但是它們是可變的,因為可以修改用const聲明的對象的屬性。
//創建一個具有兩個屬性的CAR對象const CAR = { color: "blue", price: 15000}//修改CAR的屬性CAR.price = 20000;console.log(CAR);
輸出:
{ color: 'blue', price: 20000 }
常量非常有用,可以讓將來的自己和其他程序員清楚地認識到,不應該重新分配預期的變量。如果您希望將來修改某個變量,那么您可能希望使用let來聲明該變量。
“怎么理解JavaScript中的變量、范圍和提升”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。