JavaScript 面向?qū)ο蟮哪切┦聝?/h1>

一、類與實(shí)例

1肄梨、類的聲明
// 使用構(gòu)造函數(shù)來作類的聲明
var Me = function () {
    this.name = 'pengxiaohua';
};

// es6中class的聲明
class Me2 {
    constructor () {
        this.name = 'xiaohuapeng';
    }
}
2阻荒、生成實(shí)例

生成實(shí)例,都是用new方法众羡,如下:

// 如果沒有參數(shù)侨赡,`new Me()`中的括號(hào)是可以省掉的
new Me();  // Me  {name: 'pengxiaohua'};
new Me2();  // Me2  {name: 'xiaohuapeng'};

二、類與繼承

JavaScript的繼承的基本原理還是對原型鏈的操作粱侣。

1羊壹、繼承的幾種方式
  • ① 借助構(gòu)造函數(shù)實(shí)現(xiàn)繼承
function Father () {
    this.name = 'father';
}

function Child () {
    Father.call(this);  // 將Father的this指向Child的this,此處用apply也可以
    this.type = 'child';
}

console.log(new Child());  // Child {name: "father", type: "child"}

缺點(diǎn):子類只能繼承父類構(gòu)造函數(shù)里的方法齐婴,不能繼承父類原型對象上的方法油猫,如:

Father.prototype.say = 'say Hi';

new Child()實(shí)例中是沒法繼承say方法的。

  • ② 借助原型鏈實(shí)現(xiàn)繼承
function Father2 () {
    this.name = 'father2';
}

function Child2 () {
    this.type = 'child';
}

Child2.prototype = new Father2();   // 關(guān)鍵

console.log(new Child2().__proto__);  // Father2 {name: "father2"}

根據(jù)原型鏈知識(shí)可以知道柠偶,Child2 構(gòu)造函數(shù)的實(shí)例new Child2()的__proto__屬性和 Child2 的原型prototype相等情妖,即new Child2().__proto__ === Child2.prototype,因?yàn)?code>Child2.prototype = new Father2();诱担,Child2將其原型賦值給父類Father2的實(shí)例new Father2()毡证,所以new Child2().__proto__與new Father2()相等。則new Child2()可以拿到父類 Father2 中的方法蔫仙,繼而實(shí)現(xiàn)了繼承料睛。

缺點(diǎn): 因?yàn)镃hild2 的實(shí)例對象都引用的同一個(gè)對象,即父類Father2的實(shí)例對象new Father2()匀哄,當(dāng)Child2 生成多個(gè)實(shí)例對象的時(shí)候秦效,其中一個(gè)實(shí)例對象改變,其他實(shí)例對象都會(huì)改變涎嚼,如下例子:

function Father2 () {
    this.name = 'father2';
    this.arr = [1,2,3];
}

function Child2 () {
    this.type = 'child2';
}

Child2.prototype = new Father2();   // 關(guān)鍵
var s1 = new Child2();
var s2 = new Child2();
console.log(s1.arr);
console.log(s2.arr);
// [1,2,3]
// [1,2,3]

當(dāng)修改其中一個(gè)實(shí)例化對象時(shí)阱州,另一個(gè)也會(huì)跟著改變,如下:

// 給arr添加一個(gè)數(shù)
s1.arr.push(4);
console.log(s1.arr);
console.log(s2.arr);
// [1,2,3,4]
// [1,2,3,4]
  • ③ 組合繼承
function Father3 () {
    this.name = 'father3';
    this.arr = [1,2,3];
}

function Child3 () {
    Father3.call(this);
    this.type = 'child3';
}

Child3.prototype = new Father3();
var s3 = new Child3();
var s4 = new Child3();
s3.arr.push(4);
console.log(s3.arr);
console.log(s4.arr);
// [1,2,3,4]
// [1,2,3]

組合繼承方式法梯,彌補(bǔ)了上面2中方式的缺點(diǎn)苔货。
缺點(diǎn): Father3這個(gè)父級(jí)構(gòu)造函數(shù)執(zhí)行了2次犀概,一次是子類Child3實(shí)例化new Child3()的時(shí)候,Father3.call(this)調(diào)用了一次Father3這個(gè)父級(jí)構(gòu)造函數(shù)夜惭,還有一次是Child3.prototype = new Father3();姻灶,對Father3()進(jìn)行實(shí)例化的時(shí)候。
這2次是沒有必要的诈茧,會(huì)多消耗了一點(diǎn)內(nèi)存产喉。

  • ④ 組合繼承優(yōu)化方案1
function Father4 () {
    this.name = 'father4';
    this.arr = [1,2,3];
}

function Child4 () {
    Father4.call(this);    // 拿到父類的構(gòu)造體里的屬性和方法
    this.type = 'child4';
}

Child4.prototype = Father4.prototype; // 針對第一種方法缺點(diǎn),直接繼承父類原型對象就行了
var s5 = new Child4();
var s6 = new Child4();
s5.arr.push(4);
console.log(s5.arr);
console.log(s6.arr);
// [1,2,3,4]
// [1,2,3]

這種方式通過call方法拿到父類構(gòu)造體里的屬性和方法敢会,同時(shí)通過對prototype賦值曾沈,直接繼承父類原型對象上的方法和屬性,避免了重復(fù)鸥昏。是一種比較完美的繼承方法塞俱。
但還是有一個(gè)小缺點(diǎn)的:

s5 instanceof Child4;    // true
s5 instanceof Father4;   // true
s5.constructor;
/*
Father4() {
    this.name = 'father4';
    this.arr = [1,2,3];
*/
}

當(dāng)用instanceof來判斷s5是不是Child4和Father4的實(shí)例的時(shí)候,都顯示true吏垮,表明s5都是他們2個(gè)的實(shí)例障涯。
因?yàn)閕nstanceof有時(shí)是不準(zhǔn)確的,當(dāng)用constructor來判斷的時(shí)候膳汪,發(fā)現(xiàn)s5是父類Father4的實(shí)例化唯蝶,子類Child4沒有constructor,它的constructor是從父類的constructor中繼承的旅敷,這也造成了s5雖然是子類Child4的實(shí)例生棍,但用instanceof檢測時(shí)卻既是Child4的也是Father4的實(shí)例對象颤霎。無法判斷s5這個(gè)實(shí)例是父類創(chuàng)造的還是子類創(chuàng)造的媳谁。

  • ⑤ 組合繼承優(yōu)化方案2 (寄生組合式繼承)
function Father5 () {
    this.name = 'father5';
    this.arr = [1,2,3];
}

function Child5 () {
    Father4.call(this);
    this.type = 'child5';
}

Child4.prototype = Object.create(Father5.prototype);
var s7 = new Child5();
var s8 = new Child5();
s7.arr.push(4);
console.log(s7.arr);    // [1,2,3,4]
console.log(s8.arr);    // [1,2,3]
s5 instanceof Child4;    // true
s5 instanceof Father4;   // false
s5.constructor;
/*
function Child5 () {
    Father4.call(this);
    this.type = 'child5';
}
*/

在上一種方法中,Child4.prototype = Father4.prototype;友酱,子類Child4和父類Father4的構(gòu)造函數(shù)指向的是同一個(gè)晴音,所以無法區(qū)分實(shí)例s5是通過父類還是通過子類來創(chuàng)造的。
通過Object.create()就解決了這個(gè)問題缔杉,這種方法通過锤躁、創(chuàng)建一個(gè)中間對象,把父類和子類兩個(gè)原型對象區(qū)分開或详,達(dá)到了父類和子類原型對象的一個(gè)隔離系羞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市霸琴,隨后出現(xiàn)的幾起案子椒振,更是在濱河造成了極大的恐慌,老刑警劉巖梧乘,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澎迎,死亡現(xiàn)場離奇詭異庐杨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)夹供,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門灵份,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哮洽,你說我怎么就攤上這事填渠。” “怎么了鸟辅?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵揭蜒,是天一觀的道長。 經(jīng)常有香客問我剔桨,道長屉更,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任洒缀,我火速辦了婚禮瑰谜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘树绩。我一直安慰自己萨脑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布饺饭。 她就那樣靜靜地躺著渤早,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瘫俊。 梳的紋絲不亂的頭發(fā)上鹊杖,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音扛芽,去河邊找鬼骂蓖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛川尖,可吹牛的內(nèi)容都是我干的登下。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼叮喳,長吁一口氣:“原來是場噩夢啊……” “哼被芳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起馍悟,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤畔濒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后赋朦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篓冲,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡李破,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壹将。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗤攻。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖诽俯,靈堂內(nèi)的尸體忽然破棺而出妇菱,到底是詐尸還是另有隱情,我是刑警寧澤暴区,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布闯团,位于F島的核電站,受9級(jí)特大地震影響仙粱,放射性物質(zhì)發(fā)生泄漏房交。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一伐割、第九天 我趴在偏房一處隱蔽的房頂上張望候味。 院中可真熱鬧,春花似錦隔心、人聲如沸白群。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帜慢。三九已至,卻和暖如春唯卖,著一層夾襖步出監(jiān)牢的瞬間粱玲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工耐床, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留密幔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓撩轰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昧廷。 傳聞我的和親對象是個(gè)殘疾皇子堪嫂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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

  • 目錄 導(dǎo)語 1.理解對象和面向?qū)ο蟮某绦蛟O(shè)計(jì) 2.創(chuàng)建對象的方式 3.JavaScript的繼承機(jī)制 3.1 原型...
    犯迷糊的小羊閱讀 804評論 0 4
  • class的基本用法 概述 JavaScript語言的傳統(tǒng)方法是通過構(gòu)造函數(shù),定義并生成新對象木柬。下面是一個(gè)例子: ...
    呼呼哥閱讀 4,076評論 3 11
  • 一皆串、理解對象 1.創(chuàng)建 ①構(gòu)造函數(shù) new Object ②對象字面量 var o = {}; 2.屬性類型 ①數(shù)...
    duJing閱讀 417評論 0 0
  • 記得上中學(xué)時(shí)候,曾學(xué)過一篇課文是著名作家魏巍寫的《誰是最可愛的人》眉枕,學(xué)完后我才知道是我們?nèi)嗣褡拥鼙? 現(xiàn)在恶复,...
    df872c2ae1f1閱讀 643評論 0 7
  • 01 剛下飛機(jī)就見蘇哩直奔而來怜森,給我一個(gè)大大的擁抱。她眼眶微紅谤牡,不知道是激動(dòng)副硅,還是久別重逢。但我卻推開了她翅萤,眼里滿...
    420_c644閱讀 325評論 0 0