Before Coding [18] - js的對象

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)建對象:

  1. 通過創(chuàng)建一個構(gòu)造函數(shù)來定義對象的類型纯蛾,首字母大寫是非常普遍而且很恰當(dāng)?shù)膽T用法。
  2. 通過 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ù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阅签,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蝎抽,更是在濱河造成了極大的恐慌政钟,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件樟结,死亡現(xiàn)場離奇詭異养交,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瓢宦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門碎连,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刁笙,你說我怎么就攤上這事破花∏ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵座每,是天一觀的道長前鹅。 經(jīng)常有香客問我,道長峭梳,這世上最難降的妖魔是什么舰绘? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮葱椭,結(jié)果婚禮上捂寿,老公的妹妹穿的比我還像新娘。我一直安慰自己孵运,他們只是感情好秦陋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著治笨,像睡著了一般驳概。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旷赖,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天顺又,我揣著相機(jī)與錄音,去河邊找鬼等孵。 笑死稚照,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俯萌。 我是一名探鬼主播果录,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咐熙!你這毒婦竟也來了雕憔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤糖声,失蹤者是張志新(化名)和其女友劉穎斤彼,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蘸泻,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琉苇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了悦施。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片并扇。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖抡诞,靈堂內(nèi)的尸體忽然破棺而出穷蛹,到底是詐尸還是另有隱情土陪,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布肴熏,位于F島的核電站鬼雀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛙吏。R本人自食惡果不足惜源哩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸦做。 院中可真熱鬧励烦,春花似錦、人聲如沸泼诱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽治筒。三九已至却音,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矢炼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工阿纤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留句灌,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓欠拾,卻偏偏與公主長得像胰锌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子藐窄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

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