閱讀本文需要有其他語言的編程經驗。
開始學習之前
大多數的編程語言都存在好的部分和差的部分。本文只講述JavaScript 中好的部分,這是因為:
1.僅僅學習好的部分能夠縮短學習時間
2.編寫的代碼更加健壯
3.編寫的代碼更加易讀
4.編寫的代碼更加易於維護
弱類型和強類型
通常來說,越早的修復錯誤,為之付出的代價就越小。強類型語言的編譯器可以在編譯時檢查某些錯誤。而JavaScript 是一門弱類型語言,其解釋器無法檢查類型錯誤,但實踐表明:
1.強類型能夠避免的錯誤並不是那些關鍵性錯誤
2.弱類型能夠帶來靈活性,也無需背上強類型的包袱
JavaScript 相關標準
ECMA-262 標准定義了語言ECMAScript。我們所熟知的JavaScript 和ActionScript 都是基於ECMAScript 的。目前主流使用ECMA-262 第五版,Google 的V8 引擎就是對此的實現。
Hello JavaScript
JavaScript 是一門腳本語言,需要解釋器解釋執行。你可以在瀏覽器中解釋執行JavaScript 或者直接使用node.js,node.js 整合了Google 的V8 JavaScript 引擎。由於node.js 使用非常方便,由此,這裡我使用node.js 來解釋執行JavaScript。現在看第一個JavaScript 程序:
複製代碼代碼如下:
// test.js
console.log("Hello JavaScript");
執行此程序:
複製代碼代碼如下:
node test.js
文法
註釋
JavaScript 使用和C++ 相同的註釋方式,// 用於單行註釋,/* */ 用於多行註釋。
數字類型
JavaScript 僅有一種數字類型,也就是64 位浮點數。數字類型有兩個特殊的值NaN 和Infinity,NaN 的含義為not a number(不是一個數),使用函數isNaN 檢查是否為NaN,值Infinity 表示無窮大。在Math 對像中,有一組操作數字的方法,例如:Math.floor 方法用於向下取整。
字符串
字符串literal 可以被包裹在單引號或者雙引號中,轉義字符使用/(和其他很多語言沒有什麼不同)。 JavaScript 中每個字符都是兩個字節,其使用Unicode 字符集。字符串有一個length 屬性:
複製代碼代碼如下:
"Hello".length // 值為5,注意不是"Hello".length()
字符串是不可以改變的(和Lua 一樣),除了這裡說的length 屬性,還有一些方法,例如:
複製代碼代碼如下:
'cat'.toUpperCase() === 'CAT'
語句
var 語句用於聲明局部變量,否則變量為全局變量,未初始化的變量的值為undefined:
複製代碼代碼如下:
function f() {
var localVar = 123;
globalVar = 456;
var i; // i 的值為undefined
};
f();
console.log(globalVar); // ok
console.log(localVar); // 錯誤,localVar 沒有被定義
由{} 包裹的一組語句被叫做語句塊(Block),和其他語言不同的是,JavaScript 中的函數會而塊不會創建新的作用域,例如:
複製代碼代碼如下:
{
var v = 123;
}
console.log(v); // ok
if 語句
複製代碼代碼如下:
if (expression)
statement
或者
複製代碼代碼如下:
if (expression)
statement1
else
statement2
或者
複製代碼代碼如下:
if (expression1)
statement1
else if (expression2)
statement2
else if (expression3)
statement3
else
statement4
if 語句通過判斷表達式的值為真或假來決定執行或者跳過某些語句。在JavaScript 中以下值為假(其他值均為真):
1.false
2.null
3.undefined
4.空字符串
5.0
6.NaN
if 中的statement 可以是一個語句,也可以是一個語句塊。
switch 語句
複製代碼代碼如下:
switch (n) {
case 1: // 如果n 等於1
// 執行代碼塊
break;
case 2: // 如果n 等於2
// 執行代碼塊
break;
default: // 如果n 不為1 也不為2
// 執行代碼塊
break;
}
這裡的break 用於退出循環語句或者switch 語句。在JavaScript 中,比較兩個值是否相等有兩個操作符:
1.==(對應!= 操作符),相等,兩個操作數類型不同時,此運算符嘗試操作數類型轉換後再進行比較,例如:
複製代碼代碼如下:
var x = 1;
x == 1; // true
x == "1"; // true
2.===(對應!== 操作符),完全相等,比較兩個操作數,不進行操作數類型轉換,例如:
複製代碼代碼如下:
var x = 1;
x === 1; // true
x === "1"; // false
需要注意的是NaN 和任何值都不相等,如果x 為NaN,那麼x !== x(僅對NaN 成立),我們可以這樣實現isNaN 函數:
複製代碼代碼如下:
function isNaN(n) {
return n !== n;
}
上面switch 語句,轉換為if 語句為:
複製代碼代碼如下:
if (n === 1)
// ...
else if (n === 2)
// ...
else
// ...
while 和do-while 語句
複製代碼代碼如下:
while (expression)
statement
如果expression 為真則重複執行statement 直到expression 為假。
複製代碼代碼如下:
do
statement
while (expression);
類似while 循環,只是先執行statement,然後再檢查條件expression。
for 語句
複製代碼代碼如下:
for (initialize ; test ; increment)
statement
首先initialize 被執行一次(常用來初始化循環變量),然後進行test 條件測試(常用來測試循環變量),如果test 條件為假則停止循環,否則執行statement,然後執行increment(常用來更新循環變量),接著又進行test 條件測試,如此循環執行下去。使用範例:
複製代碼代碼如下:
for (var i=0; i<5; ++i) {
console.log(i);
}
for 的另外一種形式被用於枚舉一個對象的所有屬性名:
複製代碼代碼如下:
for (variable in object)
statement
範例:
複製代碼代碼如下:
var obj = {
a: 1,
b: 2,
c: 3
};
for (var name in obj)
console.log(name);
需要注意的是,我們通過hasOwnProperty 方法來檢查屬性名是該對象的,還是從原型鏈(prototype chain,prototype 會在下一篇中介紹)中找到的:
複製代碼代碼如下:
for (var in obj) {
if (obj.hasOwnProperty(var)) {
// ...
}
}
return 語句
return 語句用於讓函數返回一個值,如果函數沒有顯式的使用return,那麼返回undefined:
複製代碼代碼如下:
function f() { }
var v = f(); // v === undefined
?: 條件操作符(JavaScript 中唯一的一個三元操作符)
?: 條件操作符在很多編程語言中都存在,在第一個操作數為真時,操作符返回第二個操作數的值,否則返回第三個操作數的值,使用範例:
複製代碼代碼如下:
function abs() {
return x > 0 ? x : -x;
}
typeof 操作符
typeof 操作符用於獲取變量的類型,其返回值包括:
1.'number'
2.'string'
3.'boolean'
4.'undefined'
5.'function'
6.'object'
特別的typeof null 返回的結果是'object'。關於typeof 的範例:
複製代碼代碼如下:
var a = typeof 'hello'; // a === 'string'
var b = typeof null; // b === 'object'
+ 操作符
+ 操作符在JavaScript 中可以用於加法運算,也可以用於字符串連接:
複製代碼代碼如下:
var message = 'hello' + 'world'; // message === 'helloworld'
&& 和|| 運算符
&& 操作符在第一個操作數為假時返回第一個操作數的值,否則返回第二個操作數的值
|| 操作符在第一個操作數為真時返回第一個操作數的值,否則返回第二個操作數的值
複製代碼代碼如下:
var a = 1 && true; // a === true
var b = 1 || false; // b === 1
|| 的一個習慣用法:
複製代碼代碼如下:
name = name || 'unknown'; // 為name 設定默認值'unknown'