Javascript 變量

2023-02-17 10:37 更新

大多數(shù)情況下,JavaScript 應(yīng)用需要處理信息。這有兩個例子:

  1. 一個網(wǎng)上商店 —— 這里的信息可能包含正在售賣的商品和購物車。
  2. 一個聊天應(yīng)用 —— 這里的信息可能包括用戶和消息等等。

變量就是用來儲存這些信息的。

變量

變量 是數(shù)據(jù)的“命名存儲”。我們可以使用變量來保存商品、訪客和其他信息。

在 JavaScript 中創(chuàng)建一個變量,我們需要用到 let 關(guān)鍵字。

下面的語句創(chuàng)建(也可以稱為 聲明 或者 定義)了一個名稱為 “message” 的變量:

let message;

現(xiàn)在,我們可以通過賦值運算符 = 為變量添加一些數(shù)據(jù):

let message;

message = 'Hello'; // 將字符串 'Hello' 保存在名為 message 的變量中

現(xiàn)在這個字符串已經(jīng)保存到與該變量相關(guān)聯(lián)的內(nèi)存區(qū)域了,我們可以通過使用該變量名稱訪問它:

let message;
message = 'Hello!';

alert(message); // 顯示變量內(nèi)容

簡潔一點,我們可以將變量定義和賦值合并成一行:

let message = 'Hello!'; // 定義變量,并且賦值

alert(message); // Hello!

也可以在一行中聲明多個變量:

let user = 'John', age = 25, message = 'Hello';

看上去代碼長度更短,但并不推薦這樣。為了更好的可讀性,請一行只聲明一個變量。

多行變量聲明有點長,但更容易閱讀:

let user = 'John';
let age = 25;
let message = 'Hello';

一些程序員采用下面的形式書寫多個變量:

let user = 'John',
  age = 25,
  message = 'Hello';

……甚至使用“逗號在前”的形式:

let user = 'John'
  , age = 25
  , message = 'Hello';

技術(shù)上講,這些變體都有一樣的效果。所以,這是個個人品味和審美方面的問題。

?var ?而不是 ?let?

在較老的腳本中,你也可能發(fā)現(xiàn)另一個關(guān)鍵字 var,而不是 let

var message = 'Hello';

var 關(guān)鍵字與 let 大體 相同,也用來聲明變量,但稍微有些不同,也有點“老派”。

let 和 var 之間有些微妙的差別,但目前對于我們來說并不重要。我們將會在 老舊的 "var" 章節(jié)中介紹它們。

一個現(xiàn)實生活的類比

如果將變量想象成一個“數(shù)據(jù)”的盒子,盒子上有一個唯一的標注盒子名字的貼紙。這樣我們能更輕松地掌握“變量”的概念。

例如,變量 message 可以被想象成一個標有 "message" 的盒子,盒子里面的值為 "Hello!"


我們可以在盒子內(nèi)放入任何值。

并且,這個盒子的值,我們想改變多少次,就可以改變多少次:

let message;

message = 'Hello!';

message = 'World!'; // 值改變了

alert(message);

當值改變的時候,之前的數(shù)據(jù)就被從變量中刪除了:


我們還可以聲明兩個變量,然后將其中一個變量的數(shù)據(jù)拷貝到另一個變量。

let hello = 'Hello world!';

let message;

// 將字符串 'Hello world' 從變量 hello 拷貝到 message
message = hello;

// 現(xiàn)在兩個變量保存著相同的數(shù)據(jù)
alert(hello); // Hello world!
alert(message); // Hello world!

聲明兩次會觸發(fā) error

一個變量應(yīng)該只被聲明一次。

對同一個變量進行重復(fù)聲明會觸發(fā) error:

let message = "This";

// 重復(fù) 'let' 會導(dǎo)致 error
let message = "That"; // SyntaxError: 'message' has already been declared

因此,我們對同一個變量應(yīng)該只聲明一次,之后在不使用 let 的情況下對其進行引用。

函數(shù)式語言

有趣的是,也存在禁止更改變量值的 函數(shù)式 編程語言。比如 Scala 或 Erlang

在這種類型的語言中,一旦值保存在盒子中,就永遠存在。如果你試圖保存其他值,它會強制創(chuàng)建一個新盒子(聲明一個新變量),無法重用之前的變量。

雖然第一次看上去有點奇怪,但是這些語言有很大的發(fā)展?jié)摿?。不僅如此,在某些領(lǐng)域,比如并行計算,這個限制有一定的好處。研究這樣的一門語言(即使不打算很快就用上它)有助于開闊視野。

變量命名

JavaScript 的變量命名有兩個限制:

  1. 變量名稱必須僅包含字母、數(shù)字、符號 ??和 ?_?。
  2. 首字符必須非數(shù)字。

有效的命名,例如:

let userName;
let test123;

如果命名包括多個單詞,通常采用駝峰式命名法(camelCase)。也就是,單詞一個接一個,除了第一個單詞,其他的每個單詞都以大寫字母開頭:myVeryLongName。

有趣的是,美元符號 '$' 和下劃線 '_' 也可以用于變量命名。它們是正常的符號,就跟字母一樣,沒有任何特殊的含義。

下面的命名是有效的:

let $ = 1; // 使用 "$" 聲明一個變量
let _ = 2; // 現(xiàn)在用 "_" 聲明一個變量

alert($ + _); // 3

下面的變量命名不正確:

let 1a; // 不能以數(shù)字開始

let my-name; // 連字符 '-' 不允許用于變量命名

區(qū)分大小寫

命名為 apple 和 APPLE 的變量是不同的兩個變量。

允許非英文字母,但不推薦

可以使用任何語言,包括西里爾字母(cyrillic letters)甚至是象形文字,就像這樣:

let имя = '...';
let 我 = '...';

從技術(shù)上講,這樣沒問題。這樣的命名是完全允許的,但是用英文進行變量命名是國際慣例。哪怕我們正在寫一個很小的腳本,它也有可能會被使用很久。某個時候,來自其他國家的人可能會需要閱讀它。

保留字

有一張 保留字列表,這張表中的保留字無法用作變量命名,因為它們被用于編程語言本身了。

比如,letclass、return、function 都被保留了。

下面的代碼將會拋出一個語法錯誤:

let let = 5; // 不能用 "let" 來命名一個變量,錯誤!
let return = 5; // 同樣,不能使用 "return",錯誤!

未采用 ?use strict? 下的賦值

一般,我們需要在使用一個變量前定義它。但是在早期,我們可以不使用 let 進行變量聲明,而可以簡單地通過賦值來創(chuàng)建一個變量?,F(xiàn)在如果我們不在腳本中使用 use strict 聲明啟用嚴格模式,這仍然可以正常工作,這是為了保持對舊腳本的兼容。

// 注意:這個例子中沒有 "use strict"

num = 5; // 如果變量 "num" 不存在,就會被創(chuàng)建

alert(num); // 5

上面這是個糟糕的做法,嚴格模式下會報錯。

"use strict";

num = 5; // 錯誤:num 未定義

常量

聲明一個常數(shù)(不變)變量,可以使用 const 而非 let

const myBirthday = '18.04.1982';

使用 const 聲明的變量稱為“常量”。它們不能被修改,如果你嘗試修改就會發(fā)現(xiàn)報錯:

const myBirthday = '18.04.1982';

myBirthday = '01.01.2001'; // 錯誤,不能對常量重新賦值

當程序員能確定這個變量永遠不會改變的時候,就可以使用 const 來確保這種行為,并且清楚地向別人傳遞這一事實。

大寫形式的常數(shù)

一個普遍的做法是將常量用作別名,以便記住那些在執(zhí)行之前就已知的難以記住的值。

使用大寫字母和下劃線來命名這些常量。

例如,讓我們以所謂的“web”(十六進制)格式為顏色聲明常量:

const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";

// ……當我們需要選擇一個顏色
let color = COLOR_ORANGE;
alert(color); // #FF7F00

好處:

  • ?COLOR_ORANGE ?比 ?"#FF7F00"? 更容易記憶。
  • 比起 ?COLOR_ORANGE ?而言,?"#FF7F00"? 更容易輸錯。
  • 閱讀代碼時,?COLOR_ORANGE ?比 ?#FF7F00? 更易懂。

什么時候該為常量使用大寫命名,什么時候進行常規(guī)命名?讓我們弄清楚一點。

作為一個“常數(shù)”,意味著值永遠不變。但是有些常量在執(zhí)行之前就已知了(比如紅色的十六進制值),還有些在執(zhí)行期間被“計算”出來,但初始賦值之后就不會改變。

例如:

const pageLoadTime = /* 網(wǎng)頁加載所需的時間 */;

pageLoadTime 的值在頁面加載之前是未知的,所以采用常規(guī)命名。但是它仍然是個常量,因為賦值之后不會改變。

換句話說,大寫命名的常量僅用作“硬編碼(hard-coded)”值的別名。

正確命名變量

談到變量,還有一件非常重要的事。

一個變量名應(yīng)該有一個清晰、明顯的含義,對其存儲的數(shù)據(jù)進行描述。

變量命名是編程過程中最重要且最復(fù)雜的技能之一??焖俚貫g覽變量的命名就知道代碼是一個初學(xué)者還是有經(jīng)驗的開發(fā)者寫的。

在一個實際項目中,大多數(shù)的時間都被用來修改和擴展現(xiàn)有的代碼庫,而不是從頭開始寫一些完全獨立的代碼。當一段時間后,我們做完其他事情,重新回到我們的代碼,找到命名良好的信息要容易得多。換句話說,變量要有個好名字。

聲明變量之前,多花點時間思考它的更好的命名。你會受益良多。

一些可以遵循的規(guī)則:

  • 使用易讀的命名,比如 ?userName ?或者 ?shoppingCart?。
  • 離諸如 ?a?、?b?、?c? 這種縮寫和短名稱遠一點,除非你真的知道你在干什么。
  • 變量名在能夠準確描述變量的同時要足夠簡潔。不好的例子就是 ?data ?和 ?value?,這樣的名稱等于什么都沒說。如果能夠非常明顯地從上下文知道數(shù)據(jù)和值所表達的含義,這樣使用它們也是可以的。
  • 腦海中的術(shù)語要和團隊保持一致。如果網(wǎng)站的訪客稱為“用戶”,則我們采用相關(guān)的變量命名,比如 ?currentUser ?或者 ?newUser?,而不要使用 ?currentVisitor ?或者一個 ?newManInTown?。

聽上去很簡單?確實如此,但是在實踐中選擇一個一目了然的變量名稱并非如此簡單。大膽試試吧。

重用還是新建?

最后一點,有一些懶惰的程序員,傾向于重用現(xiàn)有的變量,而不是聲明一個新的變量。

結(jié)果是,這個變量就像是被扔進不同東西盒子,但沒有改變它的貼紙?,F(xiàn)在里面是什么?誰知道呢。我們需要靠近一點,仔細檢查才能知道。

這樣的程序員節(jié)省了一點變量聲明的時間,但卻在調(diào)試代碼的時候損失數(shù)十倍時間。

額外聲明一個變量絕對是利大于弊的。

現(xiàn)代的 JavaScript 壓縮器和瀏覽器都能夠很好地對代碼進行優(yōu)化,所以不會產(chǎn)生性能問題。為不同的值使用不同的變量可以幫助引擎對代碼進行優(yōu)化。

總結(jié)

我們可以使用 var、let 或 const 聲明變量來存儲數(shù)據(jù)。

  • ?let ?— 現(xiàn)代的變量聲明方式。
  • ?var ?— 老舊的變量聲明方式。一般情況下,我們不會再使用它。但是,我們會在 老舊的 "var" 章節(jié)介紹 ?var ?和 ?let ?的微妙差別,以防你需要它們。
  • ?const ?— 類似于 ?let?,但是變量的值無法被修改。

變量應(yīng)當以一種容易理解變量內(nèi)部是什么的方式進行命名。

任務(wù)


使用變量

重要程度: 2

  1. 聲明兩個變量:?admin ?和 ?name?。
  2. 將值 ?"John"? 賦給 ?name?。
  3. 從 ?name ?變量中拷貝其值給 ?admin?。
  4. 使用 ?alert ?顯示 ?admin ?的值(必須輸出 “John”)。

解決方案

下面的代碼,每一行都對應(yīng)著任務(wù)列表中的對應(yīng)項。

let admin, name; // 一次聲明兩個變量。

name = "John";

admin = name;

alert( admin ); // "John"

給出正確的名字

重要程度: 3

  1. 使用我們的星球的名字創(chuàng)建一個變量。你會怎么命名這個變量?
  2. 創(chuàng)建一個變量來存儲當前瀏覽者的名字。你會怎么命名這個變量?

解決方案

代表我們星球的變量

這很簡單:

let ourPlanetName = "Earth";

注意,我們也可以用一個更簡短的名字 planet,但這樣可能并不能表達清楚它指的是哪個星球。再啰嗦一點也挺好的。至少讓這個變量別太長就行。

網(wǎng)站當前訪問者的名字

let currentUserName = "John";

同樣,如果我們的確知道用戶就是當前的用戶的話,我們可以使用更短的變量名 ?userName?。

現(xiàn)代編輯器的自動補全可以讓長變量名變得容易編寫。不要浪費這個特性。一個名字中包含三個詞挺好的。

如果你的編輯器沒有合適的自動補全功能,換 一個新的吧。


大寫的常量?

重要程度: 4

檢查下面的代碼:

const birthday = '18.04.1982';

const age = someCode(birthday);

這里我們有一個 birthday 日期常量和通過一些代碼(為了保持簡短這里沒有提供,因為這些細節(jié)在這無關(guān)緊要)從 birthday 計算出的 age 常量。

對于 birthday 使用大寫方式正確嗎?那么 age 呢?或者兩者都用?

const BIRTHDAY = '18.04.1982'; // 使用大寫?

const AGE = someCode(BIRTHDAY); // 使用大寫?

解決方案

我們通常用大寫字母表示“硬編碼(hard-coded)”的常量?;蛘?,換句話說就是,當值在執(zhí)行之前或在被寫入代碼的時候,我們就知道值是什么了。

在這個代碼中 ?birthday ?確實是這樣的。因此我們可以使用大寫。

在對照組中,?age ?是在程序運行時計算出的。今天我們有一個年齡,一年以后我們就會有另一個。它在某種意義上不會隨著代碼的執(zhí)行而改變。但與 ?birthday ?相比,它還是有一定的可變性:它是計算出來的,因此我們應(yīng)該使用小寫。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號