現代 JavaScript 教程 — 重學變量

什麼是變量

大多數狀況下,JavaScript 應用須要處理信息。這有兩個例子:javascript

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

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

變量

變量 是數據的「命名存儲」。咱們可使用變量來保存商品、訪客和其餘信息。java

在 JavaScript 中建立一個變量,咱們須要用到 let 關鍵字。react

下面的語句建立(也能夠稱爲 聲明 或者 定義)了一個名稱爲 「message」 的變量:程序員

let message;
複製代碼

如今,咱們能夠經過賦值操做符 = 爲變量添加一些數據:web

let message;

message = 'Hello'; // 保存字符串
複製代碼

如今這個字符串已經保存到與該變量相關聯的內存區域了,咱們能夠經過使用該變量名稱訪問它:編程

let message;
message = 'Hello!';

alert(message); // 顯示變量內容
複製代碼

簡潔一點,咱們能夠將變量定義和賦值合併成一行:瀏覽器

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

alert(message); // Hello!
複製代碼

也能夠在一行中聲明多個變量:微信

let user = 'John', age = 25, message = 'Hello';
複製代碼

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

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

let user = 'John';
let age = 25;
let message = 'Hello';
複製代碼

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

let user = 'John',
  age = 25,
  message = 'Hello';
複製代碼

……甚至使用「逗號在前」的形式:

let user = 'John'
  , age = 25
  , message = 'Hello';
複製代碼

技術上講,這些變體都有同樣的效果。因此,這是個我的品味和審美方面的問題。

使用 var 而不是 let

在較舊的腳本中,你也可能發現另外一個關鍵字 var,而不是 let

var message = 'Hello';
複製代碼

var 關鍵字與 let 大致 相同,也用來聲明變量,但稍微有些不一樣,也有點「老派」。

letvar 之間有些微妙的差異,但目前對於咱們來講並不重要。咱們將會在 古老的 var 這一章節中介紹它們。

一個現實生活的類比

若是將變量想象成一個「數據」的盒子,盒子上有一個惟一的標註盒子名字的貼紙。這樣咱們能更輕鬆地掌握「變量」的概念。

例如,變量 message 能夠被想象成一個標有 "message" 的盒子,盒子裏面的值爲 "Hello!"

咱們能夠在盒子內放入任何值。

而且,這個盒子的值,咱們想改變多少次,就能夠改變多少次:

let message;

message = 'Hello!';

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

alert(message);
複製代碼

當值改變的時候,以前的數據就被從變量中刪除了:

咱們還能夠聲明兩個變量,而後將其中一個變量的數據拷貝到另外一個變量。

let hello = 'Hello world!';

let message;

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

// 如今兩個變量保存着相同的數據
alert(hello); // Hello world!
alert(message); // Hello world!
複製代碼

函數式編程語言

有趣的是,也存在禁止更改變量值的 函數式 編程語言。好比 ScalaErlang

在這種類型的語言中,一旦值保存在盒子中,就永遠存在。若是你試圖保存其餘值,它會強制建立一個新盒子(聲明一個新變量),沒法重用以前的變量。

雖然第一次看上去有點奇怪,可是這些語言有很大的發展潛力。不只如此,在某些領域,好比並行計算,這個限制有必定的好處。研究這樣的一門語言(即便不打算很快就用上它)有助於開闊視野。

變量命名

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

  1. 變量名稱必須僅包含字母,數字,符號 $_
  2. 首字符必須非數字。

有效的命名,例如:

let userName;
let test123;
複製代碼

若是命名包括多個單詞,一般採用駝峯式命名法(camelCase)。也就是,單詞一個接一個,除了第一個單詞,其餘的每一個單詞都以大寫字母開頭:myVeryLongName

有趣的是,美圓符號 '$' 和下劃線 '_' 也能夠用於變量命名。它們是正常的符號,就跟字母同樣,沒有任何特殊的含義。

下面的命名是有效的:

let $ = 1; // 使用 "$" 聲明一個變量
let _ = 2; // 如今用 "_" 聲明一個變量

alert($ + _); // 3
複製代碼

下面的變量命名不正確:

let 1a; // 不能以數字開始

let my-name; // 連字符 '-' 不容許用於變量命名
複製代碼

區分大小寫

命名爲 appleAppLE 的變量是不一樣的兩個變量。

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

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

let имя = '...';
let 我 = '...';
複製代碼

技術上講,徹底沒有錯誤,這樣的命名是徹底容許的,可是用英文進行變量命名是國際傳統。哪怕咱們正在寫一個很小的腳本,它也有可能有很長的生命週期。某個時候,來自其餘國家的人可能會閱讀它。

保留字

有一張 保留字列表,這張表中的保留字沒法用做變量命名,由於它們被用於編程語言自己了。

好比,letclassreturnfunction 都被保留了。

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

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

未採用 use strict 下的賦值

通常,咱們須要在使用一個變量前定義它。可是在早期,咱們能夠不使用 let 進行變量聲明,而能夠簡單地經過賦值來建立一個變量。如今若是咱們不在腳本中使用 use strict 聲明啓用嚴格模式,這仍然能夠正常工做,這是爲了保持對舊腳本的兼容。

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

num = 5; // 若是變量 "num" 不存在,就會被建立

alert(num); // 5
複製代碼

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

"use strict";

num = 5; // 錯誤:num 爲定義
複製代碼

常量

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

const myBirthday = '18.04.1982';
複製代碼

使用 const 聲明的變量稱爲「常量」。它們不能被修改,若是你嘗試修改就會發現報錯:

const myBirthday = '18.04.1982';

myBirthday = '01.01.2001'; // 錯誤,不能對常量從新賦值
複製代碼

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

大寫形式的常數

一個廣泛的作法是將常量用道別名,以便記住那些在執行以前就已知的難以記住的值。

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

例如,讓咱們以所謂的「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 更易懂。

何時該爲常量使用大寫命名,何時進行常規命名?讓咱們弄清楚一點。

做爲一個「常數」,意味着值永遠不變。可是有些常量在執行以前就已知了(好比紅色的十六進制值),還有些在執行期間被「計算」出來,但初始賦值以後就不會改變。

例如:

const pageLoadTime = /* 網頁加載所需的時間 */;
複製代碼

pageLoadTime 的值在頁面加載以前是未知的,因此採用常規命名。可是它仍然是個常量,由於賦值以後不會改變。

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

正確命名變量

談到變量,還有一件很是重要的事。

一個變量名應該有一個清晰、明顯的含義,對其存儲的數據進行描述。

變量命名是編程過程當中最重要且最複雜的技能之一。快速地瀏覽變量的命名就知道代碼是一個初學者仍是有經驗的開發者寫的。

在一個實際項目中,大多數的時間都被用來修改和擴展示有的代碼庫,而不是從頭開始寫一些徹底獨立的代碼。當一段時間後,咱們作完其餘事情,從新回到咱們的代碼,找到命名良好的信息要容易得多。換句話說,變量要有個好名字。

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

一些能夠遵循的規則

  • 使用易讀的命名,好比 userName 或者 shoppingCart
  • 離諸如 abc 這種縮寫和短名稱遠一點,除非你真的知道你在幹什麼。
  • 變量名在可以準確描述變量的同時要足夠簡潔。很差的例子就是 datavalue,這樣的名稱等於什麼都沒說。若是可以很是明顯地從上下文知道數據和值所表達的含義,這樣使用它們也是能夠的。
  • 腦海中的術語要和團隊保持一致。若是站點的訪客稱爲「用戶」,則咱們採用相關的變量命名,好比 currentUser 或者 newUser,而不要使用 currentVisitor 或者一個 newManInTown

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

重用仍是新建

最後一點,有一些懶惰的程序員,傾向於重用現有的變量,而不是聲明一個新的變量。

結果是,這個變量就像是被扔進不一樣東西盒子,但沒有改變它的貼紙。如今裏面是什麼?誰知道呢。咱們須要靠近一點,仔細檢查才能知道。

這樣的程序員節省了一點變量聲明的時間,但卻在調試代碼的時候損失數十倍時間。

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

現代的 JavaScript 壓縮器和瀏覽器都很夠很好地對代碼進行優化,因此不會產生性能問題。爲不一樣的值使用不一樣的變量能夠幫助引擎對代碼進行優化。

總結

咱們可使用 varletconst 聲明變量來存儲數據。

  • let — 現代的變量聲明方式。
  • var — 老舊的變量聲明方式。通常狀況下,咱們不會再使用它。可是,咱們會在 info:var 章節介紹 varlet 的微妙差異,以防你須要它們。
  • const — 相似於 let,可是變量的值沒法被修改。

變量應當以一種容易理解變量內部是什麼的方式進行命名。

做業題

先本身作題目再看答案。

1. 使用變量

重要程度:⭐️⭐️

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

答案:

下面的代碼,每一行都對應着任務列表中的對應項。

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

name = "John";

admin = name;

alert( admin ); // "John"
複製代碼

2. 給出正確的名字

重要程度:⭐️⭐️⭐️

  1. 使用咱們的星球的名字建立一個變量。你會怎麼命名這個變量?
  2. 建立一個變量來存儲當前瀏覽者的名字。你會怎麼命名這個變量?

答案:

表明咱們星球的變量,這很簡單:

let ourPlanetName = "Earth";
複製代碼

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

網站當前訪問者的名字:

let currentUserName = "John";
複製代碼

一樣,若是咱們的確知道用戶就是當前的用戶的話,咱們可使用更短的變量名 userName

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

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

3. 大寫的常量?

重要程度:⭐️⭐️⭐️️⭐️

檢查下面的代碼:

const birthday = '18.04.1982';

const age = someCode(birthday);
複製代碼

這裏咱們有一個 birthday 日期常量和經過一些代碼(爲了保持簡短這裏沒有提供,由於這些細節在這可有可無)從 birthday 計算出的 age 常量。

對於 birthday 使用大寫方式正確嗎?那麼 age 呢?或者二者都用?

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

const AGE = someCode(BIRTHDAY); // 使用大寫?
複製代碼

答案:

咱們一般用大寫字母表示「硬編碼(hard-coded)」的常量。或者,換句話說就是,當值在執行以前或在被寫入代碼的時候,咱們就知道值是什麼了。

在這個代碼中 birthday 確實是這樣的。所以咱們可使用大寫。

在對照組中,age 是在程序運行時計算出的。今天咱們有一個年齡,一年之後咱們就會有另外一個。它在某種意義上不會隨着代碼的執行而改變。但與 birthday 相比,它仍是有必定的可變性:它是計算出來的,所以咱們應該使用小寫。


現代 JavaScript 教程:開源的現代 JavaScript 從入門到進階的優質教程。React 官方文檔推薦,與 MDN 並列的 JavaScript 學習教程

在線免費閱讀:zh.javascript.info/


掃描下方二維碼,關注微信公衆號「技術漫談」,訂閱更多精彩內容。

相關文章
相關標籤/搜索