第六章 面向?qū)ο蟮某绦蛟O計

  • 我們可以ECMAScript的對象想象成散列表:無非就是一組名值對连茧,其中值是數(shù)據(jù)或函數(shù)鲤拿。
  • 每個對象都是基于一個引用類型創(chuàng)建的恶迈,這個引用類型可以使第五章討論的原生類型款票,也可以是開發(fā)人員定義的類型踏幻。

6.1 理解對象

對象字面量方法

6.1.1 屬性類型

ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性枷颊。

6.2 創(chuàng)建對象

使用一個同一個接口創(chuàng)建很多對象,會產(chǎn)生大量的重復代碼该面。

6.2.1 工廠模式

<pre>
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}

var person1 = createPerson("zhang",22,"software engineer");
</pre>

工廠模式雖然解決了創(chuàng)建多個對象的問題夭苗,但是沒有解決對象識別的問題(即怎樣知道一個對象的類型)。

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

<pre>
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
}
}
var person1 = new Person("zhang",22,"doctor");
</pre>

創(chuàng)建Person的新實例隔缀,必須使用new操作符题造。以這種方式調(diào)用構(gòu)造函數(shù)實際上回經(jīng)歷四個步驟:

  1. 創(chuàng)建一個新對象;
  2. 將構(gòu)造函數(shù)的作用域賦給新對象(因此this指向了這個新對象)猾瘸;
  3. 執(zhí)行構(gòu)造函數(shù)中的代碼
  4. 返回新對象

構(gòu)造函數(shù)模式和工廠模式差別:

  • 沒有顯示創(chuàng)建對象
  • 直接將屬性和方法賦給了this對象
  • 沒有return語句

構(gòu)造函數(shù)的主要問題界赔,就是每個方法都要在每個實例上重新創(chuàng)建一次。ECMAScript中的函數(shù)是對象牵触,因此每定義一個函數(shù)淮悼,也就是實例化一個對象,不同實例上的同名函數(shù)是不相等的揽思。
<pre>
function Person(){
this.sayName = new Function("alert(this.name)"j);//與聲明函數(shù)在邏輯上是等價的
}
alert(person1.sayName == person2.sayName);//false
</pre>

6.2.3 原型模式

每個函數(shù)都有一個prototype屬性敛惊,這個屬性是一個指針,指向一個對象绰更,這個對象的用途是包含由特定類型的所有實例共享的屬性和方法。

<pre>
function Person(){

}

Person.prototype.name = "zhang";
Person.prototype.age = 22;
Person.prototype.job = "doctor";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.name = "jian";
person1.sayName();//jian

var person2 = new Person();
person2.sayName();//zhang
</pre>

1497614688(1).jpg

hasOwnProperty()方法可以檢測一個屬性是存在與實例中還是存在與原型中锡宋。這個方法(不要忘記他是從Object繼承來的)只在給定屬性存在于對象實例中時儡湾,才會返回true。

<pre>
function Person(){

}

Person.prototype.name = "zhang";
Person.prototype.age = 22;
Person.prototype.job = "doctor";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.name = "jian";
person1.sayName();

var person2 = new Person();
person2.sayName();
function Person(){

}

Person.prototype.name = "zhang";
Person.prototype.age = 22;
Person.prototype.job = "doctor";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.name = "jian";
person1.sayName();

var person2 = new Person();
person2.sayName();
</pre>

通過使用 hasOwnProperty() 方法执俩,什么時候訪問的是實例屬性徐钠,什么時候訪問的是原型屬性就一清二楚了。調(diào)用 person1.hasOwnProperty( "name") 時役首,只有當 person1 重寫 name 屬性后才會返回 true 尝丐,因為只有這時候 name 才是一個實例屬性,而非原型屬性衡奥。圖 6-2 展示了上面例子在不同情況下的實現(xiàn)與原型的關系(為了簡單起見爹袁,圖中省略了與 Person 構(gòu)造函數(shù)的關系)。

image.png

for-in方法
<pre>
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
alert(person1.hasOwnProperty("name")); //false
alert("name" in person1); //true
person1.name = "Greg";
alert(person1.name); //"Greg" ——來自實例
alert(person1.hasOwnProperty("name")); //true
alert("name" in person1); //true
alert(person2.name); //"Nicholas" ——來自原型
alert(person2.hasOwnProperty("name")); //false
alert("name" in person2); //true
delete person1.name;
alert(person1.name); //"Nicholas" ——來自原型
alert(person1.hasOwnProperty("name")); //false
alert("name" in person1); //true
</pre>

調(diào)用 "name" in person1 始終都返回 true 矮固,無論該屬性存在于實例中還是存在于原型中失息。同時使用 hasOwnProperty() 方法和 in 操作符,就可以確定該屬性到底是存在于對象中,還是存在于原型中盹兢,如下所示邻梆。

<pre>
function hasPrototypeProperty(object, name){
return !object.hasOwnProperty(name) && (name in object);
}
</pre>

更簡單的原型語法

<pre>
function Person(){
}
Person.prototype = {
name:"zhang",
sayName:function(){
alert(this.name);
}
}
</pre>

在上面的代碼中,我們將 Person.prototype 設置為等于一個以對象字面量形式創(chuàng)建的新對象绎秒。最終結(jié)果相同浦妄,但有一個例外: constructor 屬性不再指向 Person 了。前面曾經(jīng)介紹過见芹,每創(chuàng)建一個函數(shù)剂娄,就會同時創(chuàng)建它的 prototype 對象,這個對象也會自動獲得 constructor 屬性辆童。而我們在這里使用的語法宜咒,本質(zhì)上完全重寫了默認的 prototype 對象,因此constructor 屬性也就變成了新對象的 constructor 屬性(指向 Object 構(gòu)造函數(shù))把鉴,不再指向 Person 函數(shù)故黑。此時,盡管 instanceof操作符還能返回正確的結(jié)果庭砍,但通過 constructor 已經(jīng)無法確定對象的類型了场晶,如下所示。
<pre>
var friend = new Person();
alert(friend instanceof Object); //true
alert(friend instanceof Person); //true
alert(friend.constructor == Person); //false
alert(friend.constructor == Object); //true
</pre>

如果constructor很重要怠缸,可以如下代碼設置:
<pre>
function Person(){
}
Person.prototype = {
constructor : Person,
name : "Nicholas",
age : 29,
job: "Software Engineer",
sayName : function () {
alert(this.name);
}
};
</pre>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诗轻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子揭北,更是在濱河造成了極大的恐慌扳炬,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搔体,死亡現(xiàn)場離奇詭異恨樟,居然都是意外死亡,警方通過查閱死者的電腦和手機疚俱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門劝术,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呆奕,你說我怎么就攤上這事养晋。” “怎么了绳泉?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵圈纺,是天一觀的道長灯谣。 經(jīng)常有香客問我胎许,道長辜窑,這世上最難降的妖魔是什么穆碎? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮色徘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斤寂。我一直安慰自己扬蕊,他們只是感情好歇父,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布护戳。 她就那樣靜靜地躺著抗悍,像睡著了一般缴渊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上指蚁,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天酬荞,我揣著相機與錄音袜蚕,去河邊找鬼牲剃。 笑死凿傅,一個胖子當著我的面吹牛辨液,可吹牛的內(nèi)容都是我干的滔迈。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宏怔!你這毒婦竟也來了奏路?” 一聲冷哼從身側(cè)響起畴椰,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后销斟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚂踊,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡泼橘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年米愿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椎木。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡违柏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出香椎,到底是詐尸還是另有隱情漱竖,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布士鸥,位于F島的核電站,受9級特大地震影響谆级,放射性物質(zhì)發(fā)生泄漏烤礁。R本人自食惡果不足惜讼积,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脚仔。 院中可真熱鬧勤众,春花似錦、人聲如沸鲤脏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猎醇。三九已至窥突,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間硫嘶,已是汗流浹背阻问。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沦疾,地道東北人称近。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像哮塞,于是被迫代替她去往敵國和親刨秆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

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