作者 魏楷聰 發(fā)布于 2015年01月20日
一個完整的JavaScript實現(xiàn)是由以下3個不同部分組成的:
a. 核心(ECMAScript)?? b. 文檔對象模型(DOM)?? c. 瀏覽器對象模型(BOM)
> JavaScript的核心ECMAScript描述了該語言的語法和基本對象
ECMAScript是一個重要的標準,但它并不是JavaScript唯一的部分,當然,也不是唯一被標準化的部分。
ECMAScript描述了以下內(nèi)容:a. 語法; b. 類型; c. 語句; d. 關(guān)鍵字; e. 保留字; f. 運算符; g. 對象。
ECMAScript僅僅是一個描述,定義了腳本語言的所有屬性、方法和對象。其它的語言可以實現(xiàn)ECMAScript來作為功能的基準,JavaScript就是這樣。
ECMAScript并不與任何具體瀏覽器相綁定,實際上,它也沒有提到任何用戶輸入輸出的方法。每個瀏覽器都有它自己的ECMAScript接口的實現(xiàn),然后這個實現(xiàn)又被擴展,包含了DOM和BOM。
> DOM描述了處理網(wǎng)頁內(nèi)容的方法和接口
DOM(文檔對象模型)是HTML和XML的應(yīng)用程序接口(API)。DOM將把整個頁面規(guī)劃成由節(jié)點層級構(gòu)成的文檔。HTML或XML頁面的每個部分都是一個節(jié)點的衍生物。
DOM通過創(chuàng)建樹來表示文檔,從而使開發(fā)者對文檔的內(nèi)容和結(jié)構(gòu)具有空前的控制力。用DOM API可以輕松地刪除、添加和替換節(jié)點。
> BOM描述了與瀏覽器進行交互的方法和接口
BOM(瀏覽器對象模型),可以對瀏覽器窗口進行訪問和操作。使用BOM,開發(fā)者可以移動窗口、改變狀態(tài)欄中的文本以及執(zhí)行其它與頁面內(nèi)容不直接相關(guān)的動作。BOM只是JavaScript實現(xiàn)的一部分,沒有任何相關(guān)的標準。由于沒有相關(guān)的BOM標準,每種瀏覽器都有自己的BOM實現(xiàn)。
1. 原始值和引用值
在ECMAScript中,變量可以存放兩種類型的值,即原始值和引用值。
a. 原始值(primitive value)是存儲在棧(stack)中的簡單數(shù)據(jù)段,也就是說,它們的值直接存儲在變量訪問的位置。
b. 引用值(reference value)是存儲放在堆(heap)中的對象,也就是說,存儲在變量處的值是一個指針(point),指向存儲對象的內(nèi)存處。
原始類型占據(jù)的空間是固定的,將它們存儲在較小的內(nèi)存區(qū)域中——棧中,便于迅速查詢變量的值。
引用類型的存儲空間將從堆中分配。由于引用值的大小會改變,所以不能把它放在棧中,否則會降低變量查尋的速度。相反,放在變量的棧空間中的值是該對象存儲在堆中的地址。地址的大小是固定的,所以把它存儲在棧中對變量性能無任何負面影響。
> (重點)五大原始類型(primitive type):
Undefined、Null、Boolean、Number、String
1. 可以用 typeof? 運算符來判斷一個變量是屬于哪種類型:
"undefined",變量是Undefined型
"boolean",變量是Boolean型
"number",變量是Number型
"string",變量是String型
"object",變量是一種引用類型或 Null 類型
2. Undefined 類型
只有一個值,即undefined(字面量)。當聲明的變量未初始化時,該變量的默認值是undefined。但是,值undefined并不同于未定義的值,而typeof運算符并不真正區(qū)分這兩種值。
var oTemp;
// make sure this variable isn't defind
// var oTemp2;
alert(typeof oTemp); // outputs "undefined"
alert(typeof oTemp2); // outputs "undefined"
alert(oTemp2 == undefined); // cause error
對未定義的oTemp2使用除了typeof之外其它運算符,將引起錯誤,因為那些運算符只能用于已定義的變量。
當函數(shù)無明確返回值時,返回的值也是值undefined。
3. Null 類型
只有一個值,即null(字面量)。用于表示尚未存在的對象。
值undefined實際上是從值null派生來的。
alert(null == undefined);? // outputs "true"
4. Boolean 類型
有兩個值true和false(即兩個Boolean字面量)。
5. Number 類型
既可以表示32位的整數(shù),還可以表示64位的浮點數(shù)。直接輸入的(而不是從另一個變量訪問的)任何數(shù)字都被看作Number型的字面量。
整數(shù)可以被表示為八進制或十六進制的字面量,但所有數(shù)學運算返回的都是十進制結(jié)果。
浮點數(shù)字面量必須包括小數(shù)點和小數(shù)點后的一位數(shù)字,用它進行計算前,真正存儲的是字符串。
一個特殊值:NaN,表示非數(shù)(Not a Number)。
alert(isNaN("blue")); // outputs "true"
alert(isNaN("123")); // outputs "false"
6. String 類型
String類型的獨特之處在于,它是唯一沒有固定大小的原始類型。字符串字面量是由雙引號(")或單引號(')聲明的。
> 四大引用類型:Object類、Boolean類、Number類、String類
引用來型通常叫作類(class),也就是說,遇到引用值時,所處理的就是對象。ECMAScript定義了“對象定義”,邏輯上等價于其它程序設(shè)計語言中的類。
具有等價的原始類型的引用類型:
1. Object 類
Object類自身用處不大,但ECMAScript中的所有類都由這個類繼承而來,Object類中的所有屬性和方法都會出現(xiàn)在其它類中。
屬性 prototype:對該對象的對象原型的引用(指針)。對于Object類,該指針指向原始的object()函數(shù)。
方法 prototypeIsEnumerable(property):判斷給定的屬性是否可以用for...in語句進行枚舉。
2. Boolean 類
Boolean類是Boolean原始類型的引用類型。
Boolean對象將覆蓋object類的valueOf()方法,返回原始值,即true或false。toString()方法也會被覆蓋,返回字符串“true”或"false"。
建議少用Boolean對象,最好還是使用Boolean原始值。
// 在Boolean表達式中,所有對象都會被自動轉(zhuǎn)換為true
var oFlaseObject = new Boolean(false);
var bResult = oFlaseObject && true;? // outputs true
3. Number 類
創(chuàng)建Number對象并得到數(shù)字對象的Number原始值(valueOf()方法):
var oNumberObject = new Number(55);
var iNumber = oNumberObject.valueOf();
toFixed()方法返回的是具有指定位數(shù)小數(shù)的數(shù)字的字符串表示:
var oNumberObject = new Number(99);
alert(oNumberObject.toFixed(2));? // outputs "99.00"
這里,toFixed()方法的參數(shù)是2,說明了應(yīng)該顯示幾位小數(shù),空的小數(shù)位由0補充。toFixed()方法能表示具有0到20位小數(shù)的數(shù)字,超出這個范圍的值會引起錯誤。
只要可能,都使用數(shù)字的原始表示法。
4. String 類
String類是String原始類型的對象表示法。
String對象的valueOf()方法和toString()方法都會返回String類型的原始值:
var oStringObject = new String("hello world");
alert(oStringObject.valueOf() == oStringObject.toString());? // outputs "true"
String類具有屬性length,它是字符串中的字符個數(shù):
var oStringObject = new String("hello world");
alert(oStringObject.length);? // outputs "11"
String類還有大量的方法,可以查看API。
5. instanceof 運算符
instanceof運算符與typeof運算符相似,用于識別正在處理的對象的類型。與typeof方法不同的是,instanceof方法要求開發(fā)者明確地確認對象為某特定類型。
var oStringObject = new String("hello world");
alert(oStringObject instanceof String);? // outputs "true"
2. 轉(zhuǎn)換
> 簡單的轉(zhuǎn)換方法
1. 轉(zhuǎn)換成字符串
3種主要的原始值Boolean值、數(shù)字和字符串都是偽對象,都有toString()方法,可以把它們的值轉(zhuǎn)換成字符串。
Boolean型的toString()方法只是輸出“true”或“false”,結(jié)果由變量的值決定。
Number類型的toString()方法有兩種模式,即默認模式和基模式。
在默認模式中,返回的都是數(shù)字的十進制表示。
在基模式中,可以用不同的基輸出數(shù)字。
var iNum1 = 10;
alert(iNum1.toString(2));? // outputs "1010"
alert(iNum1.toString(8));? // outputs "12"
alert(iNum1.toString(16));? // outputs "A"
HTML采用十六進制數(shù)表示每種顏色,在HTML中處理數(shù)字時這種功能非常有用。
2. 轉(zhuǎn)換成數(shù)字,只轉(zhuǎn)換第一個無效字符之前的字符串
parseInt():
var iNum1 = parseInt("1234blue");? // return 1234
var iNum2 = parseInt("0xA");? // return 10
var iNum3 = parseInt("22.5");? // return 22
var iNum4 = parseInt("blue");? // return NaN
parseInt()方法的基模式:
var iNum1 = parseInt("AF", 16);? // return 175
var iNum2 = parseInt("10", 2);? // return 2
var iNum3 = parseInt("10", 8);? // return 8
var iNum4 = parseInt("10", 10);? // return 10
如果十進制數(shù)包含前導(dǎo)0,那么最好采用基數(shù)10,這樣才不會意外地得到八進制的值。
parseFloat():
var iNum1 = parseFloat("1234blue");? // return 1234
var iNum2 = parseFloat("0xA");? // return 0
var iNum3 = parseFloat("22.5");? // return 22.5
var iNum4 = parseFloat("22.34.5");? // return 22.34
var iNum5 = parseFloat("0908");? // return 908
var iNum6 = parseFloat("blue");? // return NaN
> 強制類型轉(zhuǎn)換(type casting)
1. Boolean(value):把給定的值轉(zhuǎn)換成Boolean型
當要轉(zhuǎn)換的值是至少有一個字符的字符串、非0數(shù)字或對象時,Boolean()函數(shù)將返回true。如果該值是空字符串、數(shù)字0、undefined或null,它將返回false。
var b1 = Boolean("");? // false - empty string
var b2 = Boolean("hi");? // true - non-empty string
var b3 = Boolean(100);? // true - non-zero string
var b4 = Boolean(null);? // false - null
var b5 = Boolean(0);? // false - zero
var b6 = Boolean(new Object());? // true - object
Number(value):把給定的值轉(zhuǎn)換成數(shù)字(可以是整數(shù)或浮點數(shù)),轉(zhuǎn)換的是整個值
var n1 = Number(false);? // 0
var n2 = Number(true);? // 1
var n3 = Number(undefined);? // NaN
var n4 = Number(null);? // 0
var n5 = Number("5.5");? // 5.5
var n6 = Number("56");? // 56
var n7 = Number("5.6.7");? // NaN
var n8 = Number(new Object());? // NaN
var n9 = Number(100);? // 100
String(value):把給定的值(任何值)轉(zhuǎn)換成字符串
強制轉(zhuǎn)換成字符串和調(diào)用toString()方法的唯一不同之處在于,對null或undefined值強制類型轉(zhuǎn)換可以生成字符串而不引發(fā)錯誤:
var s1 = String(null);? // "null"
var oNull = null;
var s2 = oNull.toString();? // won't work, causes an error
3. 函數(shù)
函數(shù)是ECMAScript的核心。函數(shù)(function)就是對象。
如果函數(shù)無明確的返回值,或調(diào)用了沒有參數(shù)的return語句,那么它真正返回的值是undefined。
1. 無重載:ECMAScript中的函數(shù)不能重載,沒有方法(函數(shù))重載的概念。
2. arguments對象:每個函數(shù)都有一個隱含的對象 arguments,表示給函數(shù)實際傳遞的參數(shù)
3. Function類:所有自定義的函數(shù)都是Function 對象類型的。Function 對象接收的所有參數(shù)都是字符串類型的,其中最后一個參數(shù)就是要執(zhí)行的函數(shù)體,而前面的參數(shù)則是函數(shù)真正需要接收的參數(shù)。
每一個函數(shù)對象都有一個 length 屬性,表示該函數(shù)期望接收的參數(shù)格式。它與函數(shù)的 arguments 不同,arguments.length 表示函數(shù)實際接收的參數(shù)格式。
Function對象也有與所有對象共享的標準valueOf()方法和toString()方法。這兩個方法返回的都是函數(shù)的源代碼,在調(diào)試時尤其有用。
4. 閉包
所謂閉包,是指詞法表示包括不必計算的變量的函數(shù),也就是說,該函數(shù)能使用函數(shù)外定義的變量。
(完)