javascript高級程序設計讀書筆記(五)

面向對象的程序設計

NO.1 對象

OO語言都有一個標志,就是都有類的概念,通過類可以創(chuàng)建多個具有相同屬性的方法的對象瞬项。但JS里沒有類的概念,所以它的對象也有所不同锨天。JS把對象定義為無序屬性的集合。

JS的每個對象都是基于一個引用類型創(chuàng)建的拌阴。

JS中有兩種屬性绍绘,數(shù)據(jù)屬性和訪問器屬性;
1.數(shù)據(jù)屬性:
數(shù)據(jù)屬性包含一個數(shù)據(jù)值的位置迟赃。在這個位置可以讀取和寫入值陪拘。數(shù)據(jù)屬性有四個描述其行為的特性:
Configurable:表示能否通過delete刪除屬性從而重新定義屬性。
Enumerable: 表示能否通過for-in循環(huán)返回屬性纤壁。
Writable: 表示能否修改屬性的值左刽。
Value: 包含這個屬性的數(shù)據(jù)值。

這四個是對象的默認屬性酌媒。要修改默認是屬性的特性欠痴,可以用Object.defindProperty()方法.例如:把屬性定義為只讀迄靠,把屬性定義為不能刪除等。

var book = {
_year: 2004,
edtion: 1
}
_year是一種常見的記號喇辽,表示中能通過對象方法訪問的屬性掌挚。

創(chuàng)建對象:
雖然Object構造函數(shù)和字面的方法都可以用來創(chuàng)建單個對象,但是這些方法都有明顯的缺點菩咨,就是當一個接口創(chuàng)建很多對象時吠式,會有很多重復代碼。為了解決這個問題抽米,人們使用工廠模式的一種變體特占。

工廠模式抽象了創(chuàng)建對象的具體過程,例如:

function createPerson(name, age, job){
    var o = new Object();
    o.name = name;
    p.age = age;
    o.job = job;
    o.sayname = function(){
        alert(this.name);
    };
    return o;
}

工廠模式雖然解決了對個類似對象的問題云茸,但是沒有解決對象識別問題(怎么樣知道一個對象的類型)是目。于是有了構造函數(shù)模式:

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}

var person1 = new Person("yzq", 25, "software engineer");

構造函數(shù):
構造函數(shù)和其他的函數(shù)的唯一區(qū)別是調用的方式不同,構造函數(shù)都是通過new來調用的标捺。

構造函數(shù)的問題:
構造函數(shù)雖然好用懊纳,但是在用構造函數(shù)創(chuàng)建對象時,當對象有方法時宜岛,就需要在每個構造函數(shù)里創(chuàng)建一個方法长踊。為了解決這一個問題功舀。將函數(shù)定義轉移到構造函數(shù)的外面:

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName
}
function sayName(){
        alert(this.name);
};

var person1 = new Person("yzq", 25, "software engineer");
        

原型模式:
我們創(chuàng)建的每個函數(shù)都有一個prototype(原型)屬性萍倡,這個屬性是一個指針,指向一個對象辟汰,這個對象包含由特定類型所有實例共享的屬性和方法列敲。
例子:
function Person(){};
Person.prototyoe.name = "yzq";
Person.prototyoe.age = 25;
Person.prototyoe.job = "cc"
Person.prototyoe.sayName = function(){
alert(this.name);
};

var person1 = new Person();
person1.sayName(); //"yzq"

var person2 = new Person();
person2.sayName(); //"yzq"
通過這種方式,將屬性和方法共享帖汞。

理解原型對象:
1.只要一個新函數(shù)被創(chuàng)建時戴而,就會根據(jù)一組的特定的規(guī)則為該函數(shù)創(chuàng)建一個prototype屬性。
2.這個prototype屬性是一個指針翩蘸,指向函數(shù)的原型對象所意。
3.然后在默認情況下,原型對象都會自動獲得一個構造函數(shù)屬性催首。這個屬性是指向prototype屬性所在函數(shù)的指針扶踊。例如:Person.prototype.constructor指向Person
通過構造函數(shù),可以繼續(xù)為原型對象添加其他屬性和方法郎任。
4.在創(chuàng)建了自定義的構造函數(shù)之后秧耗,其原型對象默認只會取得constructor。其他方法舶治,都是從Object繼承而來
5.當用構造函數(shù)創(chuàng)建了一個新實例后分井,實例內(nèi)部將包含一個指針為[[Prototype]]

個人理解:
Person.prototype指向原型對象车猬,原型對象的構造函數(shù)Person.prototype.constructor又指回了Person。原型對象中除了包含構造函數(shù)屬性之外尺锚,還有其他的屬性珠闰。
而真正的每個實例都包含一個內(nèi)部屬性,數(shù)值只指向Person.prototype瘫辩。實例和構造函數(shù)是沒有任何直接聯(lián)系的铸磅。

當代碼讀取某個對象的某個屬性時,都會先從對象實例本身開始杭朱,如果在實例本身中找到了給定的名字的屬性阅仔,則返回屬性的值,如果找不到弧械,則繼續(xù)搜索指針指向的原型對象八酒。例如:在調用person1.sayName()的時候,在person1中沒有找到sayName屬性刃唐,但是在person1的原型中有sayName屬性羞迷。

另外,當對象實例可以訪問原型中的屬性画饥,但是不能重寫原型中的屬性衔瓮。所以當對象實例中有原型中的同名屬性時,實例中的該同名屬性會屏蔽原型里的屬性抖甘。要想重新訪問原型里的屬性热鞍,可以用DELETE刪除實例中的屬性。

NO.2 原型和in操作符

有兩種方式使用in操作符衔彻,單獨使用和在for-in循環(huán)中使用薇宠。
單獨使用時,in操作符會通過對象能夠訪問給定屬性時艰额,返回true澄港。無論該屬性存在實例還是原型中。

alert("name in person1")一直都是true柄沮,當屬性存在時回梧。不管在實例中還是原型對象里。

要想確定屬性在對象中還是存在原型中祖搓,可以同時使用hasOwnProperty()和in操作符狱意。方法如下:
function hasPrototypeProperty(object, name)[
return !object.hasOwnproperty(name) && (name in object);
}
hasOwnproperty只有在實例中才返回true。所以以上那個函數(shù)為true時棕硫,可以判斷屬性是在原型中髓涯。

要獲取對象上所有可枚舉的實例屬性,可以使用Object.keys()方法哈扮。這個方法接受一個對象作為參數(shù)纬纪,返回一個所有屬性的字符串數(shù)組

var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"

var p1 = new Person()
p1.name = "yzq"
p1.age = 25;
var p1keys = Object.keys(p1);
alert(p1keys); // "name,age"

更簡單的原型語法:

function Person(){
}
Person.prototype = {
    name : "yzq",
    age : 25,
    sayName : function(){
        alert(this.name);
    }
}

注意:使用上面語法會導致constructor的屬性等于Object而不等于Person了蚓再。
如果constructor真的很重要,可以自己定義包各。

function Person(){
}
Person.prototype = {
    constructor : Person,
    name : "yzq",
    age : 25,
    sayName : function(){
        alert(this.name);
    }
}

NO.3原型的動態(tài)性

先創(chuàng)建實例摘仅,在修改原型,指在原型里添加屬性和方法问畅。這樣是OK的娃属。

var friend = new Preson();
Person.prototype.sayHi = function(){
 alert("hi");
}
friend.sayHi(); //"hi"

但是先創(chuàng)建實例,在重新寫整個原型护姆。這樣就會報錯矾端。

function Person(){
}
var friend = new Preson();
Person.prototype = {
    constructor : Person,
    name :"yzq",
    age :25,
    sayName: function(){
        alert(this.name);
    }
}

friend.sayName(); //error

NO.4原型模式的缺點

因為原型模式中的屬性和方法都是共用的,所以卵皂,當一個實例修改原型模型中的屬性時秩铆,其他實例中的屬性也會改變。

所以原型模式和構造函數(shù)模式一般是組合使用:


NO.5 動態(tài)原型模式

為了解決同時寫構造函數(shù)和原型這個問題灯变,于是出現(xiàn)了動態(tài)原型模式殴玛。

function person(name,age,job){
    //屬性
    this.name = name;
    this.age = age;
    this.job = job
    //方法
    if (typeof this.sayName != "function"){
        Person.prototype.sayName = function(){
            alert(this.name);
        };
    }
}

typeof this.sayName != "function"指的是當sayName方法不存在的時候,將方法放入原型中添祸。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末滚粟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子刃泌,更是在濱河造成了極大的恐慌凡壤,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔬咬,死亡現(xiàn)場離奇詭異鲤遥,居然都是意外死亡,警方通過查閱死者的電腦和手機林艘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來混坞,“玉大人狐援,你說我怎么就攤上這事【吭校” “怎么了啥酱?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長厨诸。 經(jīng)常有香客問我镶殷,道長,這世上最難降的妖魔是什么微酬? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任绘趋,我火速辦了婚禮颤陶,結果婚禮上,老公的妹妹穿的比我還像新娘陷遮。我一直安慰自己滓走,他們只是感情好,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布帽馋。 她就那樣靜靜地躺著搅方,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绽族。 梳的紋絲不亂的頭發(fā)上姨涡,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音吧慢,去河邊找鬼绣溜。 笑死,一個胖子當著我的面吹牛娄蔼,可吹牛的內(nèi)容都是我干的怖喻。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼岁诉,長吁一口氣:“原來是場噩夢啊……” “哼锚沸!你這毒婦竟也來了?” 一聲冷哼從身側響起涕癣,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤哗蜈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后坠韩,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體距潘,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年只搁,在試婚紗的時候發(fā)現(xiàn)自己被綠了音比。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡氢惋,死狀恐怖洞翩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情焰望,我是刑警寧澤骚亿,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站熊赖,受9級特大地震影響来屠,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一俱笛、第九天 我趴在偏房一處隱蔽的房頂上張望捆姜。 院中可真熱鬧,春花似錦嫂粟、人聲如沸娇未。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽零抬。三九已至,卻和暖如春宽涌,著一層夾襖步出監(jiān)牢的瞬間平夜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工卸亮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留忽妒,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓兼贸,卻偏偏與公主長得像段直,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溶诞,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

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