# 語法
JavaScript 的語法大量借鑒了 C 及其他類 C 語言(如 Java 和 Perl)的語法。因此,熟悉這些語言的開發人員在接受 JavaScript 更加寬松的語法時,一定會有種輕松自在的感覺。本章主要按照 ECMAScript 3介紹這門語言的基本概念,并就 ECMAScript 5的變化給出說明。
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#字符集)字符集
JavaScript 程序是用 Unicode 字符集編寫的,Unicode 是 ASCII 和 Latin-1 的超集,并支持地球上幾乎所有在用的語言。ECMAScript 3要求 JavaScript 的實現必須支持 Unicode 2.1及后續版本,ECMAScript 5則要求支持 Unicode 3及后續版本。
> 擴展閱讀「Unicode 與 JavaScript 詳解」
> [http://www.ruanyifeng.com/blog/2014/12/unicode.html](http://www.ruanyifeng.com/blog/2014/12/unicode.html)
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#區分大小寫)區分大小寫
JavaScript 是區分大小寫的。也就是說,關鍵字、變量、函數名和所有的標識符(identifier)都必須采取一致的大小寫形式。比如,關鍵字?`while`?必須寫成?`while`,而不能寫成?`While`?或者?`WHILE`。同樣,`online`、`Online`、`OnLine`、`ONLINE`?是4個不同的變量名。
但需要注意的是,HTML 并不區分大小寫。由于它和客戶端 JavaScript 聯系緊密,因此這點區別很容易混淆。許多客戶端 JavaScript 對象和屬性與他們所表示的 HTML 標簽和屬性名相同。在 HTML 中,這些標簽和屬性名可以使用大寫也可以是小寫,而在 JavaScript 中則必須是小寫。例如,在 HTML 中設置事件處理程序時,`onclick`?屬性可以寫成?`onClick`,但在 JavaScript 代碼中,必須使用小寫的?`onclick`。
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#注釋)注釋
JavaScript 使用 C 風格的注釋,包括單行注釋和塊級注釋。單行注釋以兩個斜杠?`//`?開頭,塊級注釋以一個斜杠和一個星號`/*`?開頭,以一個星號和一個斜杠?`*/`?結尾。下面都是合法的 JavaScript 注釋:
~~~
// 這里是單行注釋
/*
* 這里是塊級注釋
* 也叫多行注釋
*/
~~~
雖然上面注釋中的第二和第三行都以一個星號開頭,但這不是必須的,純粹是為了提高注釋的可讀性(這種格式在企業級應用中極其常見)。
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#字面量)字面量
所謂字面量(也可稱直接量,Literal values),就是程序中直接使用的數據值。字面量只代表自身,不存儲在特定位置。JavaScript 中的字面量有:字符串、數字、布爾值、對象、數組、函數、正則表達式,以及特殊的?`null`?值。
~~~
"hello world" // 字符串
123 // 數字
1.2 // 小數
true // 布爾值
false // 布爾值
/javascript/gi // 正則表達式
null // 空
{ name: 'stone', age: 20} // 對象
[ 1, 2, 3, 4, 5, 6, 7, 8 ] // 數組
function(){ console.log('good'); } // 函數
~~~
> 擴展閱讀「undefined不是字面量」
> [http://www.cnblogs.com/ziyunfei/archive/2012/11/11/2765096.html](http://www.cnblogs.com/ziyunfei/archive/2012/11/11/2765096.html)
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#嚴格模式)嚴格模式
在 ECMAScript 5引入了嚴格模式(strict mode)的概念。嚴格模式是為 JavaScript 定義了一種不同的解析與執行模式。在嚴格模式下,ECMAScript 3中的一些不確定的行為將得到處理,而且對某些不安全的操作也會拋出錯誤。要在整個腳本中啟用嚴格模式,可以在頂部添加如下代碼:
~~~
"use strict";
~~~
這行代碼看起來像是字符串,而且也沒有賦值給任何變量,但其實它是一個編譯指示(pragma),用于告訴支持的 JavaScript 引擎切換到嚴格模式。這是為了不破壞 ECMAScript 3語法而特意選定的語法。
在函數內部的第一行包含這條編譯指示,也可以指定函數在嚴格模式下執行:
~~~
function doSomething(){
"use strict";
// 函數體
}
~~~
嚴格模式下,JavaScript 的執行結果會有很大不同,因此本課程會隨時指出嚴格模式下的區別。
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#標識符)標識符
所謂標識符,就是指變量、函數、屬性的名字,或者函數的參數。JavaScript 標識符必須以字母、下劃線(`_`)或美元符號(`$`)開始,后續的字符可以是字母、數字、下劃線或美元符號(數字是不允許作為首字符出現的)。下面是合法的標識符:
~~~
my_variable_name, v12345, _dummy, $str888
~~~
標識符中的字母可以包含擴展的 ASCII 或 Unicode 字母字符(如?`π`?和?`∑`),但不推薦這樣做。按照慣例,JavaScript 標識符采用駝峰大小寫格式,也就是第一個字母小寫,剩下的每個有意義的單詞的首字母大寫,例如:
~~~
firstSecond, myCar, doSomethingImportant
~~~
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#關鍵字和保留字)關鍵字和保留字
ECMAScript 3描述了一組具有特定用途的關鍵字,這些關鍵字可用于表示控制語句的開始或結束,或者用于執行特定操作等。按照規則,關鍵字是語言保留的,不能用作標識符。以下是 ECMAScript 3的全部關鍵字:
~~~
break delete function return typeof
case do if switch var
catch else in this void
continue false instanceof throw while
debugger finally new true with
default for null try
~~~
ECMAScript 3還將 Java 的所有關鍵字都作為自己的保留字。盡管保留字還沒有任何特定的用途,但他們有可能在將來被用作關鍵字:
~~~
abstract double goto native static
boolean enum implements package super
byte export import private synchronized
char extends int protected throws
class final interface public transient
const float long short volatile
~~~
ECMAScript 5把非嚴格模式下的保留字縮減為:
~~~
class enum extends super
const export import
~~~
ECMAScript 5在嚴格模式下的保留字為:
~~~
implements package public
interface private static
let protected yield
~~~
注意,`let`?和?`yield`?是 ECMAScript 5新增的保留字,其他保留字都是 ECMAScript 3定義的。為了保證兼容性,任何時候都不建議使用 ECMAScript 5新增的保留字?`let`?和?`yield`?。
ECMAScript 還預定義了很多全局變量和函數,也應當避免把它們用作標識符:
~~~
arguments Error Math RegExp
Array eval NaN String
Boolean EvalError Number SyntaxError
Date Function Object TypeError
decodeURI Infinity parseFloat undefined
decodeURIComponent isFinite parseInt URIError
encodeURI isNaN RangeError
encodeURIComponent JSON ReferenceError
~~~
JavaScript 的具體實現可能定義獨有的全局變量和函數,每一種特定的 JavaScript 運行環境都有自己的一個全局屬性列表,這一點是需要牢記的。
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#可選的分號)可選的分號
和其他許多變成語言一樣,JavaScript 使用分號(`;`)將語句分隔開。這對增強代碼的可讀性和整潔性是非常重要的。缺少分隔符,一條語句的結束就成了下一條語句的開始,反之亦然。如果語句各自獨占一行,通常可以省略語句之間的分號(程序結尾或花括號?`}`?之前的分號也可以省略)。
~~~
var sum = a + b // 即使沒有分號也是有效的語句,不好的寫法
var diff = a - b; // 有效的語句,好的寫法
~~~
雖然語句結尾的分號不是必須的,但請任何時候都不要省略它。因為加上這個分號可以避免很多錯誤,開發人員也可以放心地通過刪除多余的空格來壓縮 JavaScript 代碼。另外,加上分號也會在某些情況下增進代碼的性能,因為這樣解析解就不必再花時間推測應該在哪插入分號了。
## [](https://github.com/stone0090/javascript-lessons/tree/master/1.3-Syntax#關卡)關卡
請判斷以下代碼是否有效?如果有效請給出結果,如果無效請說明原因。
~~~
// 挑戰一
var class = 'person';
console.log(class); // ???
~~~
~~~
// 挑戰二
var Class = 'person';
console.log(class); // ???
~~~
~~~
// 挑戰三
var True = false;
console.log(True); // ???
~~~
~~~
// 挑戰四
var true = false;
console.log(True); // ???
~~~
~~~
// 挑戰五
var $_$ = 'stone';
console.log($_$); // ???
~~~
~~~
// 挑戰六
var 00_name = 'stone';
console.log(00_name); // ???
~~~
~~~
// 挑戰七
var Array = 'null';
console.log(Array); // ???
~~~
~~~
// 挑戰八
var undefined = 'null';
console.log(undefined); // ???
~~~
~~~
// 挑戰九
var result = 1 + 2
+ 3 + 4
console.log(result); // ???
~~~