1.1 值
JavaScript里有6種基本類型的值: number、string、Boolean、object、function和undefined.
1.3.2 prompt和confirm
瀏覽器提供的標准環境包含了更多用於彈出窗口的函數,可以使用confirm函數讓用戶選擇OK/Cancel問題。該函數返回布爾值:如果用戶單擊OK,則返回true;如果單擊Cancel,則返回false。
prompt函數可用於詢問一個開放式問題,第一個參數就是該問題;第二個參數是用戶需要輸入文本的開頭部分,可以在對話窗口里輸入一行文本,該函數會將其返回作為一個字符串。
1.4 程序結構
Number函數將用戶輸入的值轉化為數字。類似的函數還有String和Boolean
2.1.5 函數值
正如在前一章中提到的,JavaScript里的所有東西都是值,包括function函數。這就是說定義的函數名稱可以像普通變量一樣使用,而且其內容可以傳遞給表達式並用於更大的表達式。在下面的示例中,如果a不是false值,程序會調用變量a里的函數;而如果a為false值,代碼則調用b函數。
var a = null; function b() { return "B"; } (a || b)();
(a || b)()這個看起來有點怪異的表達式將"調用時不傳參數"的操作符()應用到(a || b)上,如果該表達式產生的不是函數,則調用會產生錯誤。一旦產生的是函數,就會像該例中那樣,結果值被調用了。
如果僅需要一個未命名的函數值,function關鍵字可以用作一個表達式,就像這樣:
var a = null; (a || function(){ return "B"; })();
匿名表達式function(){return "B";}僅創建了一個函數值。
2.2.3 遞歸
很多開發人員的基本原則是,只有在證明程序運行太慢時才去關注效率問題。一旦出現這種情況,找出占用時間最多的代碼,然后將這些美觀的代碼改成高效的代碼。
3.2 基本數據結構
對象的屬性可以自由添加、刪除及修改。對象所扮演的主要角色,實際上就是一個屬性和對象的集合。
var cat = { color: "gray", name: "Spot", size: 46};
屬性名如果不是一個合法的變量名稱,則不可以用點標記法訪問,只能使用中括號的形式訪問。
in操作符用於判斷某個名字是否存在於集合內。
比較對象時,JavaScript中的==操作符只有在賦予的兩個值完全相同時才能返回true。比較兩個內容相同的不同的對象將返回false;(對象==指針??)
數組可以使用中括號([])來創建: var mailArchive = ["mail one", "mail two", "mail three"];
join()方法將字符串數組轉換為字符串,傳入的參數用於將數組的各個值連接起來。
3.3 解決關於Emily姨媽家貓的問題
split()方法將一個字符串分解成一個數組,以給定的字符串作為參數來確定在什么位置分解字符串。
slice()方法用於從第一個參數所在的位置開始到第二個參數所在的位置結束拷貝出一部分字符串。
charAt()方法用於從某個字符串獲取指定位置的字符。
indexOf()方法可以找出字符第一次出現的位置或者截取字符串中的子串。
3.3.6 日期表示
月份數字是從0到11;
getFullYear(), getMonth(), getDate(), getMinutes(), getSeconds(), getDay(), getTime();
測試兩個日期對象是否相等可以使用如下代碼:
var wende1 = new Date(1989, 10, 9), wende2 = new Date(1989, 10, 9); wende1.getTime() == wende2.getTime();
4.2.2 異常
throw是引發異常的關鍵字。關鍵字try用於設立異常障礙:如果代碼塊里的代碼引發異常,catch代碼塊將會執行,在執行的時候,catch后面的變量將擁有該異常值。
異常的優點:只有在錯誤的發生點以及處理錯誤的點上才需要錯誤處理代碼。兩者中間的函數可以忽略這些。
try語句后面也可以跟finally關鍵字,意思是:不管發生什么,嘗試運行try塊的代碼以后就運行這些代碼。如果函數需要清除一些東西,清除代碼通常應放在finally塊里。
function forEach(array, action) { for (var i=0; i<array.length; i++) action(array[i]); } function sum(numbers) { var total = 0; forEach(numbers, function(number){ total += number; }); return total; } print(sum([1, 2, 3, 4]));
操作其它函數的函數稱為高階函數。
5.2.1 修改函數
另一個很有用的高階函數類型修改了傳入的函數值:
function negate(func) { return function(x) { return !func(x); }; } var isNotNaN = negate(isNaN);
5.2.2 規約函數
sum函數實際上是算法的一個變體,該算法通常稱為規約(reduce):
function reduce(combine, base, array) { forEach(array, function(element){ base = combine(base, element); }); return base; } function add(a, b) { return a+b; } function sum(numbers) { return reduce(add, 0, numbers); }
5.2.3 映射數組
另外一個與數組有關的"基本算法"稱為映射(map)。它能夠遍歷數組,並且將函數應用於每個元素。但是它不會丟棄函數返回值,而是利用這些返回值重新建立一個新的數組。
function map(func, array) { var result = []; forEach(array, function(element) { result.push(func(element)); }); return result; }
第6章 面向對象編程
6.1.1 定義方法
1. 對對象添加方法的一種方式就是簡單附加一個函數值,如下面的代碼所示。
var rabbit = {}; rabbit.speak = function(line) { print("The rabbit says '", line, "'"); }; rabbit.speak("I'm alive.")
2. 對象可以看成是屬性和方法的集合,因此可以用聲明集合的方式來聲明對象 ~
function speak(line) {
alert("The " + this.adjective + " rabbit says '" + line + "'");
}
var whiteRabbit = {adjective:"white", speak:speak};
var fatRabbit = {adjective:"fat", speak:speak};
whiteRabbit.speak("Oh my ears and whiskers, how late it's getting!");
fatRabbit.speak("I could sure use a carrot right now.");
從.訪問speak()來看,這的確是一個對象。但函數與對象的耦合度未免也太低了~
apply()方法和call()方法
1. apply方法的第一個參數用於指定函數所應用的對象(對非方法函數來說,關系並不大,着也是傳入null的原因)。也可以通過下面的方式讓fatRabbit來調用speak:
speak.apply(fatRabbit, ["Yum."]);
apply(Object, args),第二個參數是speak()的參數數組 (這里speak()函數只接收一個參數) ;
2. call方法可以為函數分別給出相應的參數,而無需將其作為一個數組。
speak.call(fatRabbit, "Yum.");
3. 對於有多個參數的函數,可以按如下方式使用call和apply:
function run(from, to) { alert("The " + this.adjective + " rabbit runs from " + from + " to " + to + " ."); } run.apply(whiteRabbit, ["A", "B"]); run.call(fatRabbit, "the cupboard", "the fridge");
6.1.3 從原型中構建
為什么必須使用new關鍵字呢? 畢竟,我們只需這樣編寫:
function makeRabbit(adjective) { return { adjective: adjective, speak: function(line) {/*等等*/} }; } var blackRabbit = makeRabbit("black");
但兩者並不完全相同。new還發揮着一些其他作用。首先,killerRabbit有一個constructor屬性,指向創建該屬性的Rabbit函數。blackRabbit也有一個這樣的屬性,但它指向Object函數。
constructor屬性從何而來?它是一個rabbit屬性的一部分。雖然有點令人迷惑,但是原型是JavaScript對象工作方式中非常重要的一部分。每個對象都基於一個原型,該原型賦予其一系列基本特性。到目前為止所使用的簡單對象均基於最基本的原型,這種原型與Object構造函數相關,因此所有對象都共享該原型。(順便說一句,輸入{}相當於輸入new Object().)
