ECMAScript

ECMAScript關(guān)鍵字

delete

do

else

finally

function

in

instanceof

this

throw

try

typeof

var

with

保留字

abstract

debugger

extends

final

goto

implements

native

package

synchronized

throws

transient

volatile

ECMAScript有5種原始類型(primitive type),即Undefined、Null窿侈、Boolean肠缔、Number和String匿级。ECMA-262把術(shù)語類型(type定義為值的一個(gè)集合蛔屹,每種原始類型定義了它包含的值的范圍及其字面量表示形式。

原始值

存儲(chǔ)在棧(stack)中的簡(jiǎn)單數(shù)據(jù)段冤留,也就是說恩掷,它們的值直接存儲(chǔ)在變量訪問的位置倡鲸。

引用值

存儲(chǔ)在堆(heap)中的對(duì)象,也就是說黄娘,存儲(chǔ)在變量處的值是一個(gè)指針(point)峭状,指向存儲(chǔ)對(duì)象的內(nèi)存處。

typeof運(yùn)算符

typeof運(yùn)算符有一個(gè)參數(shù)逼争,即要檢查的變量或值优床。例如:

var sTemp = "test string";

alert (typeof sTemp);//輸出"string"

alert (typeof 86);//輸出"number"

對(duì)變量或值調(diào)用typeof運(yùn)算符將返回下列值之一:

undefined -如果變量是Undefined類型的

boolean -如果變量是Boolean類型的

number -如果變量是Number類型的

string -如果變量是String類型的

object -如果變量是一種引用類型或Null類型的

Object對(duì)象具有下列屬性:

constructor

對(duì)創(chuàng)建對(duì)象的函數(shù)的引用(指針)。對(duì)于Object對(duì)象誓焦,該指針指向原始的Object()函數(shù)胆敞。

Prototype

對(duì)該對(duì)象的對(duì)象原型的引用。對(duì)于所有的對(duì)象杂伟,它默認(rèn)返回Object對(duì)象的一個(gè)實(shí)例移层。

Object對(duì)象還具有幾個(gè)方法:

hasOwnProperty(property)

判斷對(duì)象是否有某個(gè)特定的屬性。必須用字符串指定該屬性赫粥。(例如观话,o.hasOwnProperty("name"))

IsPrototypeOf(object)

判斷該對(duì)象是否為另一個(gè)對(duì)象的原型。

PropertyIsEnumerable

判斷給定的屬性是否可以用for...in語句進(jìn)行枚舉傅是。

ToString()

返回對(duì)象的原始字符串表示匪燕。對(duì)于Object對(duì)象蕾羊,ECMA-262沒有定義這個(gè)值喧笔,所以不同的ECMAScript實(shí)現(xiàn)具有不同的值帽驯。

ValueOf()

返回最適合該對(duì)象的原始值。對(duì)于許多對(duì)象书闸,該方法返回的值都與ToString()的返回值相同尼变。

注釋:上面列出的每種屬性和方法都會(huì)被其他對(duì)象覆蓋。

instanceof運(yùn)算符

在使用typeof運(yùn)算符時(shí)采用引用類型存儲(chǔ)值會(huì)出現(xiàn)一個(gè)問題浆劲,無論引用的是什么類型的對(duì)象嫌术,它都返回"object"。ECMAScript引入了另一個(gè)Java運(yùn)算符instanceof來解決這個(gè)問題牌借。

instanceof運(yùn)算符與typeof運(yùn)算符相似度气,用于識(shí)別正在處理的對(duì)象的類型。與typeof方法不同的是膨报,instanceof方法要求開發(fā)者明確地確認(rèn)對(duì)象為某特定類型磷籍。例如:

var oStringObject = new String("hello world");

alert(oStringObject instanceof String);//輸出"true"

這段代碼問的是“變量oStringObject是否為String對(duì)象的實(shí)例?”oStringObject的確是String對(duì)象的實(shí)例现柠,因此結(jié)果是"true"院领。盡管不像typeof方法那樣靈活,但是在typeof方法返回"object"的情況下够吩,instanceof方法還是很有用的比然。

全等號(hào)由三個(gè)等號(hào)表示(===),只有在無需類型轉(zhuǎn)換運(yùn)算數(shù)就相等的情況下周循,才返回true强法。

例如:

var sNum = "66";

var iNum = 66;

alert(sNum == iNum);//輸出"true"

alert(sNum === iNum);//輸出"false"

var sNum = "66";

var iNum = 66;

alert(sNum != iNum);//輸出"false"

alert(sNum !== iNum);//輸出"true"

for (sProp in window) {

alert(sProp);

}

start : i = 5;

在這個(gè)例子中,標(biāo)簽start可以被之后的break或continue語句引用湾笛。

with語句用于設(shè)置代碼在特定對(duì)象中的作用域拟烫。

它的語法:

with (expression)statement

例如:

var sMessage = "hello";

with(sMessage) {

alert(toUpperCase());//輸出"HELLO"

}

arguments對(duì)象

在函數(shù)代碼中,使用特殊對(duì)象arguments迄本,開發(fā)者無需明確指出參數(shù)名硕淑,就能訪問它們。

function sayHi() {

if (arguments[0] == "bye") {

return;

}

alert(arguments[0]);

}

檢測(cè)參數(shù)個(gè)數(shù)

還可以用arguments對(duì)象檢測(cè)函數(shù)的參數(shù)個(gè)數(shù)嘉赎,引用屬性arguments.length即可置媳。

下面的代碼將輸出每次調(diào)用函數(shù)使用的參數(shù)個(gè)數(shù):

function howManyArgs() {

alert(arguments.length);

}

howManyArgs("string", 45);

howManyArgs();

howManyArgs(12);

上面這段代碼將依次顯示"2"、"0"和"1"公条。

模擬函數(shù)重載

用arguments對(duì)象判斷傳遞給函數(shù)的參數(shù)個(gè)數(shù)拇囊,即可模擬函數(shù)重載:

function doAdd() {

if(arguments.length == 1) {

alert(arguments[0] + 5);

} else if(arguments.length == 2) {

alert(arguments[0] + arguments[1]);

}

}

doAdd(10);//輸出"15"

doAdd(40, 20);//輸出"60"

Function對(duì)象(類)

ECMAScript最令人感興趣的可能莫過于函數(shù)實(shí)際上是功能完整的對(duì)象。

Function類可以表示開發(fā)者定義的任何函數(shù)靶橱。

用Function類直接創(chuàng)建函數(shù)的語法如下:

var function_name = new function(arg1,arg2, ...,argN,function_body)

function sayHi(sName, sMessage) {

alert("Hello " + sName + sMessage);

}

還可以這樣定義它:

var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");

function doAdd(iNum) {

alert(iNum + 20);

}

function doAdd(iNum) {

alert(iNum + 10);

}

doAdd(10);//輸出"20"

如你所知寥袭,第二個(gè)函數(shù)重載了第一個(gè)函數(shù)路捧,使doAdd(10)輸出了"20",而不是"30"传黄。

如果以下面的形式重寫該代碼塊杰扫,這個(gè)概念就清楚了:

var doAdd = new Function("iNum", "alert(iNum + 20)");

var doAdd = new Function("iNum", "alert(iNum + 10)");

doAdd(10);

請(qǐng)觀察這段代碼,很顯然膘掰,doAdd的值被改成了指向不同對(duì)象的指針章姓。函數(shù)名只是指向函數(shù)對(duì)象的引用值,行為就像其他對(duì)象一樣。甚至可以使兩個(gè)變量指向同一個(gè)函數(shù):

var doAdd = new Function("iNum", "alert(iNum + 10)");

var alsodoAdd = doAdd;

doAdd(10);//輸出"20"

alsodoAdd(10);//輸出"20"

function callAnotherFunc(fnFunction, vArgument) {

fnFunction(vArgument);

}

var doAdd = new Function("iNum", "alert(iNum + 10)");

callAnotherFunc(doAdd, 10);//輸出"20"

Function對(duì)象的length屬性

如前所述,函數(shù)屬于引用類型钾军,所以它們也有屬性和方法。

ECMAScript定義的屬性length聲明了函數(shù)期望的參數(shù)個(gè)數(shù)系忙。例如:

function doAdd(iNum) {

alert(iNum + 10);

}

function sayHi() {

alert("Hi");

}

alert(doAdd.length);//輸出"1"

alert(sayHi.length);//輸出"0"

函數(shù)doAdd()定義了一個(gè)參數(shù),因此它的length是1惠豺;sayHi()沒有定義參數(shù)银还,所以length是0。

記住耕腾,無論定義了幾個(gè)參數(shù)见剩,ECMAScript可以接受任意多個(gè)參數(shù)(最多25個(gè)),這一點(diǎn)在《函數(shù)概述》這一章中講解過扫俺。屬性length只是為查看默認(rèn)情況下預(yù)期的參數(shù)個(gè)數(shù)提供了一種簡(jiǎn)便方式苍苞。

Function對(duì)象的方法

Function對(duì)象也有與所有對(duì)象共享的valueOf()方法和toString()方法。這兩個(gè)方法返回的都是函數(shù)的源代碼狼纬,在調(diào)試時(shí)尤其有用羹呵。例如:

function doAdd(iNum) {

alert(iNum + 10);

}

document.write(doAdd.toString());//function doAdd(iNum) { alert(iNum + 10); }

閉包,指的是詞法表示包括不被計(jì)算的變量的函數(shù)疗琉,也就是說冈欢,函數(shù)可以使用函數(shù)之外定義的變量。

簡(jiǎn)單的閉包實(shí)例

在ECMAScript中使用全局變量是一個(gè)簡(jiǎn)單的閉包實(shí)例盈简。請(qǐng)思考下面這段代碼:

var sMessage = "hello world";

function sayHelloWorld() {

alert(sMessage);

}

sayHelloWorld();

復(fù)雜的閉包實(shí)例

在一個(gè)函數(shù)中定義另一個(gè)會(huì)使閉包變得更加復(fù)雜凑耻。例如:

var iBaseNum = 10;

function addNum(iNum1, iNum2) {

function doAdd() {

return iNum1 + iNum2 + iBaseNum;

}

return doAdd();

}

面向?qū)ο笳Z言的要求

一種面向?qū)ο笳Z言需要向開發(fā)者提供四種基本能力:

封裝-把相關(guān)的信息(無論數(shù)據(jù)或方法)存儲(chǔ)在對(duì)象中的能力

聚集-把一個(gè)對(duì)象存儲(chǔ)在另一個(gè)對(duì)象內(nèi)的能力

繼承-由另一個(gè)類(或多個(gè)類)得來類的屬性和方法的能力

多態(tài)-編寫能以多種方法運(yùn)行的函數(shù)或方法的能力

對(duì)象的構(gòu)成

在ECMAScript中,對(duì)象由特性(attribute)構(gòu)成柠贤,特性可以是原始值香浩,也可以是引用值。如果特性存放的是函數(shù)臼勉,它將被看作對(duì)象的方法(method)邻吭,否則該特性被看作對(duì)象的屬性(property)。

聲明和實(shí)例化

對(duì)象的創(chuàng)建方式是用關(guān)鍵字new后面跟上實(shí)例化的類的名字:

var oObject = new Object();

var oStringObject = new String();

第一行代碼創(chuàng)建了Object類的一個(gè)實(shí)例宴霸,并把它存儲(chǔ)到變量oObject中囱晴。第二行代碼創(chuàng)建了String類的一個(gè)實(shí)例膏蚓,把它存儲(chǔ)在變量oStringObject中。如果構(gòu)造函數(shù)無參數(shù)畸写,括號(hào)則不是必需的驮瞧。因此可以采用下面的形式重寫上面的兩行代碼:

var oObject = new Object;

var oStringObject = new String;

對(duì)象廢除

ECMAScript擁有無用存儲(chǔ)單元收集程序(garbage collection routine),意味著不必專門銷毀對(duì)象來釋放內(nèi)存艺糜。當(dāng)再?zèng)]有對(duì)對(duì)象的引用時(shí)剧董,稱該對(duì)象被廢除(dereference)了幢尚。運(yùn)行無用存儲(chǔ)單元收集程序時(shí)破停,所有廢除的對(duì)象都被銷毀。每當(dāng)函數(shù)執(zhí)行完它的代碼尉剩,無用存儲(chǔ)單元收集程序都會(huì)運(yùn)行真慢,釋放所有的局部變量,還有在一些其他不可預(yù)知的情況下理茎,無用存儲(chǔ)單元收集程序也會(huì)運(yùn)行黑界。

把對(duì)象的所有引用都設(shè)置為null,可以強(qiáng)制性地廢除對(duì)象皂林。例如:

var oObject = new Object;

// do something with the object here

oObject = null;

早綁定和晚綁定

所謂綁定(binding)朗鸠,即把對(duì)象的接口與對(duì)象實(shí)例結(jié)合在一起的方法。

早綁定(early binding)是指在實(shí)例化對(duì)象之前定義它的屬性和方法础倍,這樣編譯器或解釋程序就能夠提前轉(zhuǎn)換機(jī)器代碼烛占。在Java和Visual Basic這樣的語言中,有了早綁定沟启,就可以在開發(fā)環(huán)境中使用IntelliSense(即給開發(fā)者提供對(duì)象中屬性和方法列表的功能)忆家。ECMAScript不是強(qiáng)類型語言,所以不支持早綁定德迹。

另一方面芽卿,晚綁定(late binding)指的是編譯器或解釋程序在運(yùn)行前,不知道對(duì)象的類型胳搞。使用晚綁定卸例,無需檢查對(duì)象的類型,只需檢查對(duì)象是否支持屬性和方法即可肌毅。ECMAScript中的所有變量都采用晚綁定方法筷转。這樣就允許執(zhí)行大量的對(duì)象操作,而無任何懲罰芽腾。

--------------------------------

一般來說旦装,可以創(chuàng)建并使用的對(duì)象有三種:本地對(duì)象、內(nèi)置對(duì)象和宿主對(duì)象摊滔。

本地對(duì)象

ECMA-262把本地對(duì)象(native object)定義為“獨(dú)立于宿主環(huán)境的ECMAScript實(shí)現(xiàn)提供的對(duì)象”阴绢。簡(jiǎn)單來說店乐,本地對(duì)象就是ECMA-262定義的類(引用類型)。它們包括:

Object

Function

Array

String

Boolean

Number

Date

RegExp

Error

EvalError

RangeError

ReferenceError

SyntaxError

TypeError

URIError

--------------

內(nèi)置對(duì)象

ECMA-262把內(nèi)置對(duì)象(built-in object)定義為“由ECMAScript實(shí)現(xiàn)提供的呻袭、獨(dú)立于宿主環(huán)境的所有對(duì)象眨八,在ECMAScript程序開始執(zhí)行時(shí)出現(xiàn)”。這意味著開發(fā)者不必明確實(shí)例化內(nèi)置對(duì)象左电,它已被實(shí)例化了廉侧。ECMA-262只定義了兩個(gè)內(nèi)置對(duì)象,即Global和Math(它們也是本地對(duì)象篓足,根據(jù)定義段誊,每個(gè)內(nèi)置對(duì)象都是本地對(duì)象)。

相關(guān)頁面

JavaScript參考手冊(cè):Global對(duì)象

JavaScript參考手冊(cè):Math對(duì)象

--------------------

宿主對(duì)象

所有非本地對(duì)象都是宿主對(duì)象(host object)栈拖,即由ECMAScript實(shí)現(xiàn)的宿主環(huán)境提供的對(duì)象连舍。

所有BOM和DOM對(duì)象都是宿主對(duì)象。

相關(guān)頁面

JavaScript高級(jí)教程:JavaScript實(shí)現(xiàn)

W3School參考手冊(cè):JavaScript參考手冊(cè)

W3School教程:HTML DOM教程

-------------------------------

作用域指的是變量的適用范圍涩哟。

公用索赏、私有和受保護(hù)作用域

概念

在傳統(tǒng)的面向?qū)ο蟪绦蛟O(shè)計(jì)中,主要關(guān)注于公用和私有作用域贴彼。公用作用域中的對(duì)象屬性可以從對(duì)象外部訪問潜腻,即開發(fā)者創(chuàng)建對(duì)象的實(shí)例后,就可使用它的公用屬性器仗。而私有作用域中的屬性只能在對(duì)象內(nèi)部訪問融涣,即對(duì)于外部世界來說,這些屬性并不存在青灼。這意味著如果類定義了私有屬性和方法暴心,則它的子類也不能訪問這些屬性和方法。

受保護(hù)作用域也是用于定義私有的屬性和方法杂拨,只是這些屬性和方法還能被其子類訪問专普。

ECMAScript只有公用作用域

對(duì)ECMAScript討論上面這些作用域幾乎毫無意義,因?yàn)镋CMAScript中只存在一種作用域-公用作用域弹沽。ECMAScript中的所有對(duì)象的所有屬性和方法都是公用的檀夹。因此,定義自己的類和對(duì)象時(shí)策橘,必須格外小心炸渡。記住,所有屬性和方法默認(rèn)都是公用的丽已!

建議性的解決方法

許多開發(fā)者都在網(wǎng)上提出了有效的屬性作用域模式蚌堵,解決了ECMAScript的這種問題。

由于缺少私有作用域,開發(fā)者確定了一個(gè)規(guī)約吼畏,說明哪些屬性和方法應(yīng)該被看做私有的督赤。這種規(guī)約規(guī)定在屬性前后加下劃線:

obj._color_ = "blue";

這段代碼中,屬性color是私有的泻蚊。注意躲舌,下劃線并不改變屬性是公用屬性的事實(shí),它只是告訴其他開發(fā)者性雄,應(yīng)該把該屬性看作私有的没卸。

有些開發(fā)者還喜歡用單下劃線說明私有成員,例如:obj._color秒旋。

靜態(tài)作用域

靜態(tài)作用域定義的屬性和方法任何時(shí)候都能從同一位置訪問约计。在Java中,類可具有屬性和方法滩褥,無需實(shí)例化該類的對(duì)象病蛉,即可訪問這些屬性和方法炫加,例如java.net.URLEncoder類瑰煎,它的函數(shù)encode()就是靜態(tài)方法。

ECMAScript沒有靜態(tài)作用域

嚴(yán)格來說俗孝,ECMAScript并沒有靜態(tài)作用域酒甸。不過,它可以給構(gòu)造函數(shù)提供屬性和方法赋铝。還記得嗎插勤,構(gòu)造函數(shù)只是函數(shù)。函數(shù)是對(duì)象革骨,對(duì)象可以有屬性和方法农尖。例如:

function sayHello() {

alert("hello");

}

sayHello.alternate = function() {

alert("hi");

}

sayHello();//輸出"hello"

sayHello.alternate();//輸出"hi"

-------------------------------------

this的功能

在ECMAScript中,要掌握的最重要的概念之一是關(guān)鍵字this的用法良哲,它用在對(duì)象的方法中盛卡。關(guān)鍵字this總是指向調(diào)用該方法的對(duì)象,例如:

var oCar = new Object;

oCar.color = "red";

oCar.showColor = function() {

alert(this.color);

};

oCar.showColor();//輸出"red"

---------------------------------

使用this的原因

為什么使用this呢筑凫?因?yàn)樵趯?shí)例化對(duì)象時(shí)滑沧,總是不能確定開發(fā)者會(huì)使用什么樣的變量名。使用this巍实,即可在任何多個(gè)地方重用同一個(gè)函數(shù)滓技。請(qǐng)思考下面的例子:

function showColor() {

alert(this.color);

};

var oCar1 = new Object;

oCar1.color = "red";

oCar1.showColor = showColor;

var oCar2 = new Object;

oCar2.color = "blue";

oCar2.showColor = showColor;

oCar1.showColor();//輸出"red"

oCar2.showColor();//輸出"blue"

例如,函數(shù)createCar()可用于封裝前面列出的創(chuàng)建car對(duì)象的操作:

function createCar() {

var oTempCar = new Object;

oTempCar.color = "blue";

oTempCar.doors = 4;

oTempCar.mpg = 25;

oTempCar.showColor = function() {

alert(this.color);

};

return oTempCar;

}

var oCar1 = createCar();

var oCar2 = createCar();

------------------------------------

為函數(shù)傳遞參數(shù)

我們還可以修改createCar()函數(shù)棚潦,給它傳遞各個(gè)屬性的默認(rèn)值令漂,而不是簡(jiǎn)單地賦予屬性默認(rèn)值:

function createCar(sColor,iDoors,iMpg) {

var oTempCar = new Object;

oTempCar.color = sColor;

oTempCar.doors = iDoors;

oTempCar.mpg = iMpg;

oTempCar.showColor = function() {

alert(this.color);

};

return oTempCar;

}

var oCar1 = createCar("red",4,23);

var oCar2 = createCar("blue",3,25);

oCar1.showColor();//輸出"red"

oCar2.showColor();//輸出"blue"

TIY

給createCar()函數(shù)加上參數(shù),即可為要?jiǎng)?chuàng)建的car對(duì)象的color、doors和mpg屬性賦值叠必。這使兩個(gè)對(duì)象具有相同的屬性外潜,卻有不同的屬性值。

在工廠函數(shù)外定義對(duì)象的方法

雖然ECMAScript越來越正式化挠唆,但創(chuàng)建對(duì)象的方法卻被置之不理处窥,且其規(guī)范化至今還遭人反對(duì)。一部分是語義上的原因(它看起來不像使用帶有構(gòu)造函數(shù)new運(yùn)算符那么正規(guī))玄组,一部分是功能上的原因滔驾。功能原因在于用這種方式必須創(chuàng)建對(duì)象的方法。前面的例子中俄讹,每次調(diào)用函數(shù)createCar()哆致,都要?jiǎng)?chuàng)建新函數(shù)showColor(),意味著每個(gè)對(duì)象都有自己的showColor()版本患膛。而事實(shí)上摊阀,每個(gè)對(duì)象都共享同一個(gè)函數(shù)。

有些開發(fā)者在工廠函數(shù)外定義對(duì)象的方法踪蹬,然后通過屬性指向該方法胞此,從而避免這個(gè)問題:

function showColor() {

alert(this.color);

}

function createCar(sColor,iDoors,iMpg) {

var oTempCar = new Object;

oTempCar.color = sColor;

oTempCar.doors = iDoors;

oTempCar.mpg = iMpg;

oTempCar.showColor = showColor;

return oTempCar;

}

var oCar1 = createCar("red",4,23);

var oCar2 = createCar("blue",3,25);

oCar1.showColor();//輸出"red"

oCar2.showColor();//輸出"blue"

-------------------------------------------

構(gòu)造函數(shù)方式

創(chuàng)建構(gòu)造函數(shù)就像創(chuàng)建工廠函數(shù)一樣容易。第一步選擇類名跃捣,即構(gòu)造函數(shù)的名字漱牵。根據(jù)慣例,這個(gè)名字的首字母大寫疚漆,以使它與首字母通常是小寫的變量名分開酣胀。除了這點(diǎn)不同,構(gòu)造函數(shù)看起來很像工廠函數(shù)娶聘。請(qǐng)考慮下面的例子:

function Car(sColor,iDoors,iMpg) {

this.color = sColor;

this.doors = iDoors;

this.mpg = iMpg;

this.showColor = function() {

alert(this.color);

};

}

var oCar1 = new Car("red",4,23);

var oCar2 = new Car("blue",3,25);

下面為您解釋上面的代碼與工廠方式的差別闻镶。首先在構(gòu)造函數(shù)內(nèi)沒有創(chuàng)建對(duì)象,而是使用this關(guān)鍵字丸升。使用new運(yùn)算符構(gòu)造函數(shù)時(shí)铆农,在執(zhí)行第一行代碼前先創(chuàng)建一個(gè)對(duì)象,只有用this才能訪問該對(duì)象发钝。然后可以直接賦予this屬性顿涣,默認(rèn)情況下是構(gòu)造函數(shù)的返回值(不必明確使用return運(yùn)算符)。

現(xiàn)在酝豪,用new運(yùn)算符和類名Car創(chuàng)建對(duì)象涛碑,就更像ECMAScript中一般對(duì)象的創(chuàng)建方式了。

你也許會(huì)問孵淘,這種方式在管理函數(shù)方面是否存在于前一種方式相同的問題呢蒲障?是的。

-------------------------------------------

原型方式

該方式利用了對(duì)象的prototype屬性,可以把它看成創(chuàng)建新對(duì)象所依賴的原型揉阎。

這里庄撮,首先用空構(gòu)造函數(shù)來設(shè)置類名。然后所有的屬性和方法都被直接賦予prototype屬性毙籽。我們重寫了前面的例子洞斯,代碼如下:

function Car() {

}

Car.prototype.color = "blue";

Car.prototype.doors = 4;

Car.prototype.mpg = 25;

Car.prototype.showColor = function() {

alert(this.color);

};

var oCar1 = new Car();

var oCar2 = new Car();

alert(oCar1 instanceof Car);//輸出"true"

-------------------------------------

原型方式的問題

原型方式看起來是個(gè)不錯(cuò)的解決方案。遺憾的是坑赡,它并不盡如人意烙如。

首先,這個(gè)構(gòu)造函數(shù)沒有參數(shù)毅否。使用原型方式亚铁,不能通過給構(gòu)造函數(shù)傳遞參數(shù)來初始化屬性的值,因?yàn)镃ar1和Car2的color屬性都等于"blue"螟加,doors屬性都等于4徘溢,mpg屬性都等于25。這意味著必須在對(duì)象創(chuàng)建后才能改變屬性的默認(rèn)值捆探,這點(diǎn)很令人討厭然爆,但還沒完。真正的問題出現(xiàn)在屬性指向的是對(duì)象徐许,而不是函數(shù)時(shí)施蜜。函數(shù)共享不會(huì)造成問題,但對(duì)象卻很少被多個(gè)實(shí)例共享雌隅。請(qǐng)思考下面的例子:

function Car() {

}

Car.prototype.color = "blue";

Car.prototype.doors = 4;

Car.prototype.mpg = 25;

Car.prototype.drivers = new Array("Mike","John");

Car.prototype.showColor = function() {

alert(this.color);

};

var oCar1 = new Car();

var oCar2 = new Car();

oCar1.drivers.push("Bill");

alert(oCar1.drivers);//輸出"Mike,John,Bill"

alert(oCar2.drivers);//輸出"Mike,John,Bill"

-------------------------------------------

混合的構(gòu)造函數(shù)/原型方式

聯(lián)合使用構(gòu)造函數(shù)和原型方式,就可像用其他程序設(shè)計(jì)語言一樣創(chuàng)建對(duì)象缸沃。這種概念非常簡(jiǎn)單恰起,即用構(gòu)造函數(shù)定義對(duì)象的所有非函數(shù)屬性,用原型方式定義對(duì)象的函數(shù)屬性(方法)趾牧。結(jié)果是检盼,所有函數(shù)都只創(chuàng)建一次,而每個(gè)對(duì)象都具有自己的對(duì)象屬性實(shí)例翘单。

我們重寫了前面的例子吨枉,代碼如下:

function Car(sColor,iDoors,iMpg) {

this.color = sColor;

this.doors = iDoors;

this.mpg = iMpg;

this.drivers = new Array("Mike","John");

}

Car.prototype.showColor = function() {

alert(this.color);

};

var oCar1 = new Car("red",4,23);

var oCar2 = new Car("blue",3,25);

oCar1.drivers.push("Bill");

alert(oCar1.drivers);//輸出"Mike,John,Bill"

alert(oCar2.drivers);//輸出"Mike,John"

--------------------------------

function StringBuffer () {

this._strings_ = new Array();

}

StringBuffer.prototype.append = function(str) {

this._strings_.push(str);

};

StringBuffer.prototype.toString = function() {

return this._strings_.join("");

};

這段代碼首先要注意的是strings屬性,本意是私有屬性哄芜。它只有兩個(gè)方法貌亭,即append()和toString()方法。append()方法有一個(gè)參數(shù)认臊,它把該參數(shù)附加到字符串?dāng)?shù)組中圃庭,toString()方法調(diào)用數(shù)組的join方法,返回真正連接成的字符串。要用StringBuffer對(duì)象連接一組字符串剧腻,可以用下面的代碼:

var buffer = new StringBuffer ();

buffer.append("hello ");

buffer.append("world");

var result = buffer.toString();

-----------------------------

通過使用ECMAScript拘央,不僅可以創(chuàng)建對(duì)象,還可以修改已有對(duì)象的行為书在。

prototype屬性不僅可以定義構(gòu)造函數(shù)的屬性和方法灰伟,還可以為本地對(duì)象添加屬性和方法。

創(chuàng)建新方法

通過已有的方法創(chuàng)建新方法

可以用prototype屬性為任何已有的類定義新方法儒旬,就像處理自己的類一樣袱箱。例如,還記得Number類的toString()方法嗎义矛?如果給它傳遞參數(shù)16发笔,它將輸出十六進(jìn)制的字符串。如果這個(gè)方法的參數(shù)是2凉翻,那么它將輸出二進(jìn)制的字符串了讨。我們可以創(chuàng)建一個(gè)方法,可以把數(shù)字對(duì)象直接轉(zhuǎn)換為十六進(jìn)制字符串制轰。創(chuàng)建這個(gè)方法非常簡(jiǎn)單:

Number.prototype.toHexString = function() {

return this.toString(16);

};

在此環(huán)境中前计,關(guān)鍵字this指向Number的實(shí)例,因此可完全訪問Number的所有方法垃杖。有了這段代碼男杈,可實(shí)現(xiàn)下面的操作:

var iNum = 15;

alert(iNum.toHexString());//輸出"F"

---------------------------

重命名已有方法

我們還可以為已有的方法命名更易懂的名稱。例如调俘,可以給Array類添加兩個(gè)方法enqueue()和dequeue()伶棒,只讓它們反復(fù)調(diào)用已有的push()和shift()方法即可:

Array.prototype.enqueue = function(vItem) {

this.push(vItem);

};

Array.prototype.dequeue = function() {

return this.shift();

};

----------------------------

添加與已有方法無關(guān)的方法

當(dāng)然,還可以添加與已有方法無關(guān)的方法彩库。例如肤无,假設(shè)要判斷某個(gè)項(xiàng)在數(shù)組中的位置,沒有本地方法可以做這種事情骇钦。我們可以輕松地創(chuàng)建下面的方法:

Array.prototype.indexOf = function (vItem) {

for (var i=0; i

if (vItem == this[i]) {

return i;

}

}

return -1;

}

var aColors = new Array("red","green","blue");

alert(aColors.indexOf("green"));//輸出"1"

---------------------------

為本地對(duì)象添加新方法

最后宛渐,如果想給ECMAScript中每個(gè)本地對(duì)象添加新方法,必須在Object對(duì)象的prototype屬性上定義它眯搭。前面的章節(jié)我們講過窥翩,所有本地對(duì)象都繼承了Object對(duì)象,所以對(duì)Object對(duì)象做任何改變鳞仙,都會(huì)反應(yīng)在所有本地對(duì)象上寇蚊。例如,如果想添加一個(gè)用警告輸出對(duì)象的當(dāng)前值的方法繁扎,可以采用下面的代碼:

Object.prototype.showValue = function () {

alert(this.valueOf());

};

var str = "hello";

var iNum = 25;

str.showValue();//輸出"hello"

iNum.showValue();//輸出"25"

-----------------------------

重定義已有方法

就像能給已有的類定義新方法一樣幔荒,也可重定義已有的方法糊闽。如前面的章節(jié)所述,函數(shù)名只是指向函數(shù)的指針爹梁,因此可以輕松地指向其他函數(shù)右犹。如果修改了本地方法,如toString()姚垃,會(huì)出現(xiàn)什么情況呢念链?

Function.prototype.toString = function() {

return "Function code hidden";

}

前面的代碼完全合法,運(yùn)行結(jié)果完全符合預(yù)期:

function sayHi() {

alert("hi");

}

alert(sayHi.toString());//輸出"Function code hidden"

--------------------------------

Function.prototype.originalToString = Function.prototype.toString;

Function.prototype.toString = function() {

if (this.originalToString().length > 100) {

return "Function too long to display.";

} else {

return this.originalToString();

}

};

function sayHi() {

alert("hi");

}

document.write(sayHi.toString());

//

function sayHi() { alert("hi"); }

---------------------------------

其原理如下:構(gòu)造函數(shù)使用this關(guān)鍵字給所有屬性和方法賦值(即采用類聲明的構(gòu)造函數(shù)方式)积糯。因?yàn)闃?gòu)造函數(shù)只是一個(gè)函數(shù)掂墓,所以可使ClassA構(gòu)造函數(shù)成為ClassB的方法,然后調(diào)用它看成。ClassB就會(huì)收到ClassA的構(gòu)造函數(shù)中定義的屬性和方法君编。例如,用下面的方式定義ClassA和ClassB:

function ClassA(sColor) {

this.color = sColor;

this.sayColor = function () {

alert(this.color);

};

}

function ClassB(sColor) {

}

還記得嗎川慌?關(guān)鍵字this引用的是構(gòu)造函數(shù)當(dāng)前創(chuàng)建的對(duì)象吃嘿。不過在這個(gè)方法中,this指向的所屬的對(duì)象梦重。這個(gè)原理是把ClassA作為常規(guī)函數(shù)來建立繼承機(jī)制兑燥,而不是作為構(gòu)造函數(shù)。如下使用構(gòu)造函數(shù)ClassB可以實(shí)現(xiàn)繼承機(jī)制:

function ClassB(sColor) {

this.newMethod = ClassA;

this.newMethod(sColor);

delete this.newMethod;

}

在這段代碼中琴拧,為ClassA賦予了方法newMethod(請(qǐng)記住降瞳,函數(shù)名只是指向它的指針)。然后調(diào)用該方法蚓胸,傳遞給它的是ClassB構(gòu)造函數(shù)的參數(shù)sColor挣饥。最后一行代碼刪除了對(duì)ClassA的引用,這樣以后就不能再調(diào)用它赢织。

所有新屬性和新方法都必須在刪除了新方法的代碼行后定義亮靴。否則,可能會(huì)覆蓋超類的相關(guān)屬性和方法:

function ClassB(sColor, sName) {

this.newMethod = ClassA;

this.newMethod(sColor);

delete this.newMethod;

this.name = sName;

this.sayName = function () {

alert(this.name);

};

}

為證明前面的代碼有效于置,可以運(yùn)行下面的例子:

var objA = new ClassA("blue");

var objB = new ClassB("red", "John");

objA.sayColor();//輸出"blue"

objB.sayColor();//輸出"red"

objB.sayName();//輸出"John"

------------------------

對(duì)象冒充可以實(shí)現(xiàn)多重繼承

有趣的是,對(duì)象冒充可以支持多重繼承贞岭。也就是說八毯,一個(gè)類可以繼承多個(gè)超類。用UML表示的多重繼承機(jī)制如下圖所示:

例如瞄桨,如果存在兩個(gè)類ClassX和ClassY话速,ClassZ想繼承這兩個(gè)類,可以使用下面的代碼:

function ClassZ() {

this.newMethod = ClassX;

this.newMethod();

delete this.newMethod;

this.newMethod = ClassY;

this.newMethod();

delete this.newMethod;

}

----------------------------------

call()方法

call()方法是與經(jīng)典的對(duì)象冒充方法最相似的方法芯侥。它的第一個(gè)參數(shù)用作this的對(duì)象泊交。其他參數(shù)都直接傳遞給函數(shù)自身乳讥。例如:

function sayColor(sPrefix,sSuffix) {

alert(sPrefix + this.color + sSuffix);

};

var obj = new Object();

obj.color = "blue";

sayColor.call(obj, "The color is ", "a very nice color indeed.");

在這個(gè)例子中,函數(shù)sayColor()在對(duì)象外定義廓俭,即使它不屬于任何對(duì)象云石,也可以引用關(guān)鍵字this。對(duì)象obj的color屬性等于blue研乒。調(diào)用call()方法時(shí)汹忠,第一個(gè)參數(shù)是obj,說明應(yīng)該賦予sayColor()函數(shù)中的this關(guān)鍵字值是obj雹熬。第二個(gè)和第三個(gè)參數(shù)是字符串宽菜。它們與sayColor()函數(shù)中的參數(shù)sPrefix和sSuffix匹配,最后生成的消息"The color is blue, a very nice color indeed."將被顯示出來竿报。

要與繼承機(jī)制的對(duì)象冒充方法一起使用該方法铅乡,只需將前三行的賦值烈菌、調(diào)用和刪除代碼替換即可:

function ClassB(sColor, sName) {

//this.newMethod = ClassA;

//this.newMethod(color);

//delete this.newMethod;

ClassA.call(this, sColor);

this.name = sName;

this.sayName = function () {

alert(this.name);

};

}

------------------------

apply()方法

apply()方法有兩個(gè)參數(shù)阵幸,用作this的對(duì)象和要傳遞給函數(shù)的參數(shù)的數(shù)組。例如:

function sayColor(sPrefix,sSuffix) {

alert(sPrefix + this.color + sSuffix);

};

var obj = new Object();

obj.color = "blue";

sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));

這個(gè)例子與前面的例子相同僧界,只是現(xiàn)在調(diào)用的是apply()方法侨嘀。調(diào)用apply()方法時(shí),第一個(gè)參數(shù)仍是obj捂襟,說明應(yīng)該賦予sayColor()函數(shù)中的this關(guān)鍵字值是obj咬腕。第二個(gè)參數(shù)是由兩個(gè)字符串構(gòu)成的數(shù)組,與sayColor()函數(shù)中的參數(shù)sPrefix和sSuffix匹配葬荷,最后生成的消息仍是"The color is blue, a very nice color indeed."涨共,將被顯示出來。

該方法也用于替換前三行的賦值宠漩、調(diào)用和刪除新方法的代碼:

function ClassB(sColor, sName) {

//this.newMethod = ClassA;

//this.newMethod(color);

//delete this.newMethod;

ClassA.apply(this, new Array(sColor));

this.name = sName;

this.sayName = function () {

alert(this.name);

};

}

同樣的举反,第一個(gè)參數(shù)仍是this,第二個(gè)參數(shù)是只有一個(gè)值color的數(shù)組扒吁』鸨牵可以把ClassB的整個(gè)arguments對(duì)象作為第二個(gè)參數(shù)傳遞給apply()方法:

function ClassB(sColor, sName) {

//this.newMethod = ClassA;

//this.newMethod(color);

//delete this.newMethod;

ClassA.apply(this, arguments);

this.name = sName;

this.sayName = function () {

alert(this.name);

};

}

---------------------------

在上一章學(xué)過,prototype對(duì)象是個(gè)模板雕崩,要實(shí)例化的對(duì)象都以這個(gè)模板為基礎(chǔ)魁索。總而言之盼铁,prototype對(duì)象的任何屬性和方法都被傳遞給那個(gè)類的所有實(shí)例粗蔚。原型鏈利用這種功能來實(shí)現(xiàn)繼承機(jī)制。

如果用原型方式重定義前面例子中的類饶火,它們將變?yōu)橄铝行问剑?/p>

function ClassA() {

}

ClassA.prototype.color = "blue";

ClassA.prototype.sayColor = function () {

alert(this.color);

};

function ClassB() {

}

ClassB.prototype = new ClassA();

原型方式的神奇之處在于突出顯示的藍(lán)色代碼行鹏控。這里致扯,把ClassB的prototype屬性設(shè)置成ClassA的實(shí)例。這很有意思当辐,因?yàn)橄胍狢lassA的所有屬性和方法抖僵,但又不想逐個(gè)將它們ClassB的prototype屬性。還有比把ClassA的實(shí)例賦予prototype屬性更好的方法嗎瀑构?

注意:調(diào)用ClassA的構(gòu)造函數(shù)裆针,沒有給它傳遞參數(shù)。這在原型鏈中是標(biāo)準(zhǔn)做法寺晌。要確保構(gòu)造函數(shù)沒有任何參數(shù)世吨。

與對(duì)象冒充相似,子類的所有屬性和方法都必須出現(xiàn)在prototype屬性被賦值后呻征,因?yàn)樵谒百x值的所有方法都會(huì)被刪除耘婚。為什么?因?yàn)閜rototype屬性被替換成了新對(duì)象陆赋,添加了新方法的原始對(duì)象將被銷毀沐祷。所以,為ClassB類添加name屬性和sayName()方法的代碼如下:

function ClassB() {

}

ClassB.prototype = new ClassA();

ClassB.prototype.name = "";

ClassB.prototype.sayName = function () {

alert(this.name);

};

可通過運(yùn)行下面的例子測(cè)試這段代碼:

var objA = new ClassA();

var objB = new ClassB();

objA.color = "blue";

objB.color = "red";

objB.name = "John";

objA.sayColor();

objB.sayColor();

objB.sayName();

此外攒岛,在原型鏈中赖临,instanceof運(yùn)算符的運(yùn)行方式也很獨(dú)特。對(duì)ClassB的所有實(shí)例灾锯,instanceof為ClassA和ClassB都返回true兢榨。例如:

var objB = new ClassB();

alert(objB instanceof ClassA);//輸出"true"

alert(objB instanceof ClassB);//輸出"true"

----------------------

混合方式

這種繼承方式使用構(gòu)造函數(shù)定義類,并非使用任何原型顺饮。對(duì)象冒充的主要問題是必須使用構(gòu)造函數(shù)方式吵聪,這不是最好的選擇。不過如果使用原型鏈兼雄,就無法使用帶參數(shù)的構(gòu)造函數(shù)了吟逝。開發(fā)者如何選擇呢?答案很簡(jiǎn)單赦肋,兩者都用块攒。

在前一章,我們?cè)?jīng)講解過創(chuàng)建類的最好方式是用構(gòu)造函數(shù)定義屬性佃乘,用原型定義方法局蚀。這種方式同樣適用于繼承機(jī)制,用對(duì)象冒充繼承構(gòu)造函數(shù)的屬性恕稠,用原型鏈繼承prototype對(duì)象的方法。用這兩種方式重寫前面的例子扶欣,代碼如下:

function ClassA(sColor) {

this.color = sColor;

}

ClassA.prototype.sayColor = function () {

alert(this.color);

};

function ClassB(sColor, sName) {

ClassA.call(this, sColor);

this.name = sName;

}

ClassB.prototype = new ClassA();

ClassB.prototype.sayName = function () {

alert(this.name);

};

在此例子中鹅巍,繼承機(jī)制由兩行突出顯示的藍(lán)色代碼實(shí)現(xiàn)千扶。在第一行突出顯示的代碼中,在ClassB構(gòu)造函數(shù)中骆捧,用對(duì)象冒充繼承ClassA類的sColor屬性澎羞。在第二行突出顯示的代碼中,用原型鏈繼承ClassA類的方法敛苇。由于這種混合方式使用了原型鏈妆绞,所以instanceof運(yùn)算符仍能正確運(yùn)行。

下面的例子測(cè)試了這段代碼:

var objA = new ClassA("blue");

var objB = new ClassB("red", "John");

objA.sayColor();//輸出"blue"

objB.sayColor();//輸出"red"

objB.sayName();//輸出"John"

------------------------------------

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枫攀,一起剝皮案震驚了整個(gè)濱河市括饶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌来涨,老刑警劉巖图焰,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蹦掐,居然都是意外死亡技羔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門卧抗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藤滥,“玉大人,你說我怎么就攤上這事社裆∽景恚” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵浦马,是天一觀的道長(zhǎng)时呀。 經(jīng)常有香客問我,道長(zhǎng)晶默,這世上最難降的妖魔是什么谨娜? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮磺陡,結(jié)果婚禮上趴梢,老公的妹妹穿的比我還像新娘。我一直安慰自己币他,他們只是感情好坞靶,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蝴悉,像睡著了一般彰阴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拍冠,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天尿这,我揣著相機(jī)與錄音簇抵,去河邊找鬼。 笑死射众,一個(gè)胖子當(dāng)著我的面吹牛碟摆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播叨橱,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼典蜕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了罗洗?” 一聲冷哼從身側(cè)響起愉舔,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎栖博,沒想到半個(gè)月后屑宠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仇让,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年典奉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丧叽。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卫玖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出踊淳,到底是詐尸還是另有隱情假瞬,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布迂尝,位于F島的核電站脱茉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏垄开。R本人自食惡果不足惜琴许,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望溉躲。 院中可真熱鬧榜田,春花似錦、人聲如沸锻梳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疑枯。三九已至辩块,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庆捺。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工古今, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滔以。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像氓拼,于是被迫代替她去往敵國(guó)和親你画。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品桃漾,去做同樣的事情坏匪,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。簡(jiǎn)單...
    舟漁行舟閱讀 7,718評(píng)論 2 17
  • 本人是android開發(fā)的,由于最近React Native的火熱,再加上自己完全不懂JS的語法,俗話說的好"落后...
    Bui_vlee閱讀 279評(píng)論 0 0
  • 我基本從來不寫工作的事兒撬统。 因?yàn)楣ぷ鲗?shí)在沒啥好寫的适滓,不就是工作唄。 然後今天打算稍微寫一點(diǎn)恋追,就寫JS吧凭迹。 我一直相...
    LostAbaddon閱讀 1,429評(píng)論 22 21
  • 一、let 和 constlet:變量聲明, const:只讀常量聲明(聲明的時(shí)候賦值)苦囱。 let 與 var 的...
    dadage456閱讀 757評(píng)論 0 0
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,212評(píng)論 0 4