【JavaScript 教程】第二章基礎(chǔ)知識(shí)02—JavaScript 變量

英文?|?https://www.javascripttutorial.net/
譯文 | 楊小愛(ài)
在上節(jié)中,我們學(xué)習(xí)了JavaScript的語(yǔ)法,錯(cuò)過(guò)的小伙伴可以點(diǎn)擊文章《【JavaScript 教程】第二章基礎(chǔ)知識(shí)01—JavaScript 語(yǔ)法》進(jìn)行學(xué)習(xí)。
那么,在今天的內(nèi)容中,我們將一起來(lái)學(xué)習(xí) JavaScript 變量以及如何在 JavaScript 中聲明變量。
JavaScript 變量是松散類(lèi)型,也就是說(shuō),變量可以保存任何類(lèi)型數(shù)據(jù)的值。變量只是值的命名占位符。
使用var關(guān)鍵字聲明JavaScript變量
要聲明變量,請(qǐng)使用var關(guān)鍵字后跟變量名稱(chēng),如下所示:
var message;
變量名可以是任何有效的標(biāo)識(shí)符。該message變量聲明,并舉行特別值undefined。
聲明變量后,您可以為變量分配一個(gè)字符串,如下所示:
message = "Hello";
要同時(shí)聲明變量并初始化它,請(qǐng)使用以下語(yǔ)法:
var variableName = value;
例如,以下語(yǔ)句聲明message變量并為其賦值"Hello"
var message = "Hello";
您可以使用一個(gè)語(yǔ)句聲明兩個(gè)或多個(gè)變量,每個(gè)變量聲明用逗號(hào) ( ,)分隔,如下所示:
var message = "Hello",counter = 100;
如前所述,您可以在message變量中存儲(chǔ)一個(gè)數(shù)字,如下例所示,但不推薦這樣做。
message = 100;
未定義與未聲明的變量
var message;console.log(message); // undefinedconsole.log(counter); // ReferenceError: counter is not defined
在此示例中,message變量已聲明但未初始化,因此其值為undefined,而counter變量尚未聲明,因此,訪問(wèn)它會(huì)導(dǎo)致ReferenceError。
全局和局部變量
在 JavaScript 中,所有變量都存在于一個(gè)范圍內(nèi),該范圍決定了變量的生命周期以及代碼的哪一部分可以訪問(wèn)它們。
JavaScript 主要有全局作用域和函數(shù)作用域。ES6 引入了一個(gè)新的作用域,稱(chēng)為塊作用域。
如果在函數(shù)中聲明一個(gè)變量,JavaScript 會(huì)將變量添加到函數(shù)作用域中。如果您在函數(shù)外部聲明變量,JavaScript 會(huì)將其添加到全局作用域。
在 JavaScript 中,您可以按如下方式定義一個(gè)函數(shù):
function functionName() {// logic}
并使用以下語(yǔ)法調(diào)用該函數(shù):
functionName();
您將在函數(shù)教程中更詳細(xì)地了解函數(shù)。
以下示例定義了一個(gè)名為say的函數(shù),該函數(shù)具有一個(gè)名為message的局部變量。
function say() {var message = "Hi";return message;}
該message變量是一個(gè)局部變量。換句話說(shuō),它只存在于函數(shù)內(nèi)部。
如果您嘗試訪問(wèn)message函數(shù)的外部,如下面的示例所示,您將得到 a,ReferenceError因?yàn)樵搈essage變量未定義:
function say() {var message = 'Hi';}console.log(message); // ReferenceError
可變陰影
請(qǐng)參閱以下示例:
// global variablevar message = "Hello";function say() {// local variablevar message = 'Hi';console.log(message); // which message?}say();// Hiconsole.log(message); // Hello
在這個(gè)例子中,我們有兩個(gè)共享相同名稱(chēng)的變量:message。?第一個(gè)message變量是全局變量,而第二個(gè)變量是局部變量。
在say()函數(shù)內(nèi)部,全局消息變量被隱藏。它不能在say()函數(shù)內(nèi)部訪問(wèn),但可以在函數(shù)外部訪問(wèn)。這稱(chēng)為可變陰影。
訪問(wèn)函數(shù)內(nèi)部的全局變量
請(qǐng)參閱以下示例:
// global variablevar message = "Hello";function say() {// local variablemessage = 'Hi';console.log(message); // which message?}say();// Hiconsole.log(message); // Hi
在這個(gè)例子中,我們定義了一個(gè)名為message的全局變量。在say()函數(shù)中,我們通過(guò)message省略var關(guān)鍵字來(lái)引用全局變量,并將其值更改為字符串 Hi。
盡管可以在函數(shù)內(nèi)部引用全局變量,但不建議這樣做。這是因?yàn)槿肿兞亢茈y維護(hù)并且可能會(huì)引起很多混亂。
非嚴(yán)格模式
下面的示例定義了一個(gè)函數(shù)并聲明了一個(gè)變量message。但是,var不使用關(guān)鍵字。
function say() {message = 'Hi'; // what?console.log(message);}say(); // Hiconsole.log(message); // Hi
當(dāng)您執(zhí)行腳本時(shí),它會(huì)在輸出Hi中輸出兩次字符串。
因?yàn)楫?dāng)我們調(diào)用say()函數(shù)時(shí),JavaScript 引擎會(huì)查找message在函數(shù)作用域內(nèi)命名的變量。
結(jié)果,它找不到任何使用該名稱(chēng)聲明的變量,因此它會(huì)進(jìn)入下一個(gè)直接作用域,在這種情況下是全局作用域,并詢(xún)問(wèn)message是否已聲明該變量。
因?yàn)?JavaScript 引擎找不到任何命名的全局變量,所以message它創(chuàng)建了一個(gè)具有該名稱(chēng)的新變量并將其添加到全局范圍。
嚴(yán)格模式
為了避免由于省略var關(guān)鍵字而在函數(shù)內(nèi)部意外創(chuàng)建全局變量,您可以通過(guò)使用"use strict";嚴(yán)格模式在 JavaScript 文件(或函數(shù))的開(kāi)頭添加來(lái),如下所示:
"use strict";function say() {message = 'Hi'; // ReferenceErrorconsole.log(message);}say(); // Hiconsole.log(message); // Hi
從現(xiàn)在開(kāi)始,您應(yīng)該始終在 JavaScript 代碼中使用嚴(yán)格模式來(lái)消除一些 JavaScript 靜默錯(cuò)誤并使您的代碼運(yùn)行得更快。
JavaScript 變量提升
在執(zhí)行 JavaScript 代碼時(shí),JavaScript 引擎會(huì)經(jīng)歷兩個(gè)階段:
解析
執(zhí)行
在解析階段,如果變量是全局變量,JavaScript 引擎會(huì)將所有變量聲明移至文件頂部,如果變量在函數(shù)中聲明,則移至函數(shù)頂部。
在執(zhí)行階段,JavaScript 引擎為變量賦值并執(zhí)行代碼。
提升是一種機(jī)制,JavaScript 引擎將所有變量聲明移動(dòng)到其作用域的頂部,無(wú)論是函數(shù)作用域還是全局作用域。
如果使用var關(guān)鍵字聲明變量,則該變量會(huì)被提升到其封閉作用域的頂部,無(wú)論是全局作用域還是函數(shù)作用域。
因此,如果您在聲明之前訪問(wèn)變量,則該變量的計(jì)算結(jié)果為undefined。
請(qǐng)參閱以下示例:
console.log(message); // undefinedvar message;
JavaScript 引擎將message變量的聲明移到頂部,因此上面的代碼等效于以下內(nèi)容:
var message;console.log(message); // undefined
如果沒(méi)有提升,你會(huì)得到一個(gè)ReferenceError,因?yàn)槟阋昧艘粋€(gè)未定義的變量。
看另一個(gè)例子:
console.log(counter);var counter = 100;
JavaScript 引擎僅將變量的聲明移至頂部。但是,它保持變量的初始分配保持不變。因此,上面的代碼等價(jià)于下面的代碼:
var counter;console.log(counter); // undefinedcounter = 100;
提升使用冗余var聲明而沒(méi)有任何懲罰:
var counter;var counter;counter = 1;console.log(counter); // 1
使用let和const關(guān)鍵字
從 ES6 開(kāi)始,您可以使用let關(guān)鍵字來(lái)聲明一個(gè)或多個(gè)變量。該let 關(guān)鍵字是類(lèi)似的var關(guān)鍵字。但是,使用let關(guān)鍵字聲明的變量是塊范圍的,而不是函數(shù)或全局范圍的var關(guān)鍵字。
JavaScript 中的塊用花括號(hào) (?{ } ) 表示。例如,if...else, do...while, 或forloop 語(yǔ)句創(chuàng)建一個(gè)塊。
下面的示例tmp在由花括號(hào)包圍的塊中聲明變量{}。
該tmp變量只存在該塊的內(nèi)部。因此,如果您在塊外引用它,您將得到一個(gè)ReferenceError.
var a = 20, b = 10;{let tmp = a;a = b;b = tmp;}console.log(tmp); // ReferenceError
該const關(guān)鍵字的工作方式類(lèi)似于let關(guān)鍵字,但你聲明變量,必須立即用值初始化,并且該值不能改變之后。
代碼語(yǔ)言:JavaScript ( javascript )const pi= 3.14;pi = 3.141; // TypeError: `code` is read-only
現(xiàn)在,您應(yīng)該對(duì) JavaScript 變量的工作原理有了一個(gè)很好的了解。
閱讀推薦
【JavaScript教程】第一章入門(mén)01——認(rèn)識(shí)JavaScript
【JavaScript教程】第一章入門(mén)02—JavaScript代碼編輯器及網(wǎng)頁(yè)開(kāi)發(fā)工具
【JavaScript 教程】第一章入門(mén)03— Hello World 示例
【JavaScript 教程】第二章基礎(chǔ)知識(shí)01—JavaScript 語(yǔ)法
學(xué)習(xí)更多技能
請(qǐng)點(diǎn)擊中國(guó)公眾號(hào)
![]()

