3.9 對象
必備知識:前面課程的學(xué)習(xí)
本章是難點(diǎn)章節(jié)剪撬,主要有以下幾個部分:
- 對象
- 屬性
- 對象的創(chuàng)建
- 方法
- 通過 this 引用對象
對象
JavaScript 采用了簡單的基于對象的范型。一個對象就是一系列屬性的集合,一個屬性包含一個名字和一個值。一個屬性的值可以是函數(shù)蝙泼,這種情況下屬性也被稱為方法氯材。除了瀏覽器里面預(yù)定義的那些對象之外,你也可以定義你自己的對象欧芽。本章節(jié)講述了怎么使用對象、屬性挤悉、函數(shù)和方法渐裸,怎樣實(shí)現(xiàn)自定義對象。
JavaScript 中的對象(物體)装悲,和其它編程語言中的對象一樣昏鹃,可以比照現(xiàn)實(shí)生活中的對象(物體)來理解它。 JavaScript 中對象(物體)的概念可以比照著現(xiàn)實(shí)生活中實(shí)實(shí)在在的物體來理解诀诊。
在 洞渤,JavaScript 中,一個對象可以是一個單獨(dú)的擁有屬性和類型的實(shí)體属瓣。我們拿它和一個杯子做下類比载迄。一個杯子是一個對象(物體),JavaScript 對象也有屬性來定義它的特征抡蛙。
屬性
一個 护昧,JavaScript 對象有很多屬性。一個對象的屬性可以被解釋成一個附加到對象上的變量粗截。對象的屬性和普通的 惋耙,JavaScript 變量基本沒什么區(qū)別,僅僅是屬性屬于某個對象熊昌。屬性定義了對象的特征绽榛,你可以通過點(diǎn)符號來訪問一個對象的屬性。
objectName.propertyName
和其他 婿屹,JavaScript 變量一樣灭美,對象的名字(可以是普通的變量)和屬性的名字都是大小寫敏感的。你可以在定義一個屬性的時候就給它賦值昂利。例如届腐,我們創(chuàng)建一個 myCar 的對象然后給他三個屬性铁坎,make,model犁苏,year厢呵。具體如下所示:
var myCar = new Object();
myCar.make = "Ford";
myCar.model = "Mustang";
myCar.year = 1969;
注:對象中未賦值的屬性的值為 undefined(而不是 null)。
JavaScript 對象的屬性也可以通過方括號訪問或者設(shè)置(更多信息查看 property accessors)傀顾。對象有時也被叫作關(guān)聯(lián)數(shù)組,因?yàn)槊總€屬性都有一個用于訪問它的字符串值碌奉。例如短曾,你可以按如下方式訪問 myCar 對象的屬性:
myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;
一個對象的屬性名可以是任何有效的 JavaScript 字符串,,或者可以被轉(zhuǎn)換為字符串的任何類型赐劣,包括空字符串嫉拐。然而怀骤,一個屬性的名稱如果不是一個有效的 JavaScript 標(biāo)識符(例如冤馏,一個由空格或連字符,或者以數(shù)字開頭的屬性名)敬矩,就只能通過方括號標(biāo)記訪問咐汞。這個標(biāo)記法在屬性名稱是動態(tài)判定(屬性名只有到運(yùn)行時才能判定)時非常有用盖呼。例如:
var myObj = new Object(),
str = "myString",
rand = Math.random(),
obj = new Object();
myObj.type = "Dot syntax";
myObj["date created"] = "String with space";
myObj[str] = "String value";
myObj[rand] = "Random Number";
myObj[obj] = "Object";
myObj[""] = "Even an empty string";
console.log(myObj);
你也可以通過存儲在變量中的字符串來訪問屬性:
var propertyName = "make";
myCar[propertyName] = "Ford";
propertyName = "model";
myCar[propertyName] = "Mustang";
你可以在 for...in 語句中使用方括號標(biāo)記以枚舉一個對象的所有屬性。為了展示它如何工作化撕,下面的函數(shù)當(dāng)你將對象及其名稱作為參數(shù)傳入時几晤,顯示對象的屬性:
function showProps(obj, objName) {
var result = "";
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
result += objName + "." + i + " = " + obj[i] + "\n";
}
}
return result;
}
因而,對于函數(shù)調(diào)用showProps(myCar, "myCar")
將返回以下值:
myCar.make = Ford
myCar.model = Mustang
myCar.year = 1969
對象的創(chuàng)建
使用對象初始化器創(chuàng)建對象
除了通過構(gòu)造函數(shù)創(chuàng)建對象之外植阴,你也可以通過對象初始化器創(chuàng)建對象蟹瘾。使用對象初始化器也被稱作通過字面值創(chuàng)建對象。對象初始化器與 C++ 術(shù)語相一致掠手。
通過對象初始化器創(chuàng)建對象的語法如下:
var obj = { property_1: value_1, // property_# may be an identifier...
2: value_2, // or a number...
// ...,
"property n": value_n }; // or a string
這里 obj 是新對象的名稱憾朴,每一個 property_i 是一個標(biāo)識符(可以是一個名稱、數(shù)字或字符串字面量)喷鸽,并且每個 value_i 是一個其值將被賦予 property_i 的表達(dá)式众雷。obj 與賦值是可選的;如果你不需要在其他地方引用對象魁衙,你就不需要將它賦給一個變量报腔。
下面的語句只有當(dāng) cond 表達(dá)式的值為 true 時創(chuàng)建對象并將其賦給變量 x:
if (cond) var x = {hi: "there"};
下例創(chuàng)建了有三個屬性的 myHonda 對象,注意它的 engine 屬性也是一個擁有自己屬性的對象:
var myHonda = {color: "red", wheels: 4, engine: {cylinders: 4, size: 2.2}};
使用構(gòu)造函數(shù)創(chuàng)建對象
作為另一種方式剖淀,你可以通過兩步來創(chuàng)建對象:
- 通過創(chuàng)建一個構(gòu)造函數(shù)來定義對象的類型纯蛾,首字母大寫是非常普遍而且很恰當(dāng)?shù)膽T用法。
- 通過 new 創(chuàng)建對象實(shí)例纵隔。
為了定義對象類型翻诉,為對象類型創(chuàng)建一個函數(shù)以聲明類型的名稱炮姨、屬性和方法。例如碰煌,你想為汽車創(chuàng)建一個類型舒岸,并且將這類對象稱為 car ,并且擁有屬性 make, model, 和 year芦圾,你可以創(chuàng)建如下的函數(shù):
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
注:我們通過使用 this 關(guān)鍵字將傳入函數(shù)的值賦給對象的屬性蛾派。
現(xiàn)在你可以象這樣創(chuàng)建一個 mycar 對象:
var mycar = new Car("Eagle", "Talon TSi", 1993);
該創(chuàng)建了 mycar 并且將指定的值賦給它的屬性。因而 mycar.make 的值是字符串 "Eagle"个少, mycar.year 的值是整數(shù) 1993洪乍,依此類推。
你可以通過調(diào)用 new 創(chuàng)建任意數(shù)量的 car 對象夜焦。例如:
var kenscar = new Car("Nissan", "300ZX", 1992);
var vpgscar = new Car("Mazda", "Miata", 1990);
一個對象的屬性值可以是另一個對象壳澳。例如,假設(shè)你按如下方式定義了 person 對象:
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
然后按如下方式創(chuàng)建了兩個 person 實(shí)例:
var rand = new Person("Rand McKinnon", 33, "M");
var ken = new Person("Ken Jones", 39, "M");
那么茫经,你可以重寫 car 的定義以包含一個擁有它的 owner 屬性巷波,如:
function Car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
}
你可以按如下方式創(chuàng)建新對象:
var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);
注意在創(chuàng)建新對象時,上面的語句將 rand 和 ken 作為 owner 的參數(shù)值卸伞,而不是傳入字符串字面量或整數(shù)值抹镊。接下來你如果想找出 car2 的擁有者的姓名,你可以訪問如下屬性:
car2.owner.name
你總是可以為之前定義的對象增加新的屬性瞪慧。例如髓考,
car1.color = "black";
為 car1 增加了 color 屬性,并將其值設(shè)為 "black" 然而弃酌,這并不影響其他的對象氨菇。想要為某個類型的所有對象增加新屬性,你必須將屬性加入到 car 對象類型的定義中妓湘。
補(bǔ)充:為對象類型定義屬性
你可以通過 prototype 屬性為之前定義的對象類型增加屬性查蓉。這為該類型的所有對象,而不是僅僅一個對象增加了一個屬性榜贴。下面的代碼為所有類型為 car 的對象增加了 color 屬性豌研,然后為對象 car1 的 color 屬性賦值:
Car.prototype.color = null;
car1.color = "black";
方法
為對象定義方法
一個方法是關(guān)聯(lián)到某個對象的函數(shù),或者簡單地說唬党,一個方法是一個值為某個函數(shù)的對象屬性鹃共。定義方法就像定義普通的函數(shù),除了它們必須被賦給對象的某個屬性驶拱。
objectName.methodname = function_name;
var myObj = {
myMethod: function(params) {
// ...do something
}
};
這里 objectName 是一個已經(jīng)存在的對象霜浴,methodname 是方法的名稱,而 function_name 是函數(shù)的名稱蓝纲。
你可以在對象的上下文中象這樣調(diào)用方法:
object.methodname(params);
你可以在對象的構(gòu)造函數(shù)中包含方法定義來為某個對象類型定義方法阴孟。例如晌纫,你可以為之前定義的 car 對象定義一個函數(shù)格式化并顯示其屬性:
function displayCar() {
var result = "A Beautiful " + this.year + " " + this.make
+ " " + this.model;
pretty_print(result);
}
這里 pretty_print
是一個顯示橫線和一個字符串的函數(shù)。注意使用 this 指代方法所屬的對象永丝。
你可以在對象定義中通過增加下述語句將這個函數(shù)變成 car 的方法:
this.displayCar = displayCar;
因此锹漱,car 的完整定義看上去將是:
function Car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
this.displayCar = displayCar;
}
按如下方式為每個對象調(diào)用 displayCar
方法:
car1.displayCar(); // A Beautiful 1993 Eagle Talon TSi
car2.displayCar(); // A Beautiful 1992 Nissan 300ZX
通過 this 引用對象
JavaScript 有一個特殊的關(guān)鍵字 this,它可以在方法中使用以指代當(dāng)前對象慕嚷。例如哥牍,假設(shè)你有一個名為 validate 的函數(shù),它根據(jù)給出的最大與最小值檢查某個對象的 value 屬性:
function validate(obj, lowval, hival) {
if ((obj.value < lowval) || (obj.value > hival))
alert("Invalid Value!");
}
然后喝检,你可以在每個元素的 onchange 事件處理器中調(diào)用 validate砂心,并通過 this 傳入相應(yīng)元素,代碼如下:
<input type="text" name="age" size="3" onChange="validate(this, 18, 99)">
總的說來蛇耀, this 在一個方法中指調(diào)用的對象。
當(dāng)與 form 屬性一起使用時坎弯,this 可以指代當(dāng)前對象的父窗體纺涤。在下面的例子中,窗體 myForm 包含一個 Text 對象和一個按鈕抠忘,當(dāng)用戶點(diǎn)擊按鍵撩炊,Text 對象的值被設(shè)為窗體的名稱。按鈕的 onclick 事件處理器使用 this.form 以指代其父窗體崎脉,即 myForm拧咳。
<form name="myForm">
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
<p><input name="button1" type="button" value="Show Form Name"
onclick="this.form.text1.value = this.form.name">
</p>
</form>
類和對象是面向?qū)ο笳Z言的經(jīng)典話題,關(guān)于對象的知識囚灼,未來在介紹 python 的時候會有更加詳細(xì)的闡述骆膝。
本節(jié)任務(wù)
- 學(xué)習(xí)慕課網(wǎng)提供的
《JavaScript進(jìn)階篇》中 剩下章節(jié) 的內(nèi)容,并完成練習(xí)(選做)灶体。