js 對(duì)象繼承

/*
    約定
*/

function Fun(){
    //私有屬性
    var val = 1;                             //私有基本屬性
    var arr = [1];                         //私有引入屬性
    function fun(){};                       //私有函數(shù)(引用屬性)

    //實(shí)例屬性
    this.val = 1;                           //實(shí)例基本屬性
    this.arr = [1];                       //實(shí)例引用屬性
    this.fun = function(){};                 //實(shí)例函數(shù)(引用屬性);
};

//原型屬性
Fun.prototype.val = "jack";               //原型基本屬性
Fun.prototype.arr = [1];                     //原型引用屬性
Fun.prototype.fun = function(){};           //原型函數(shù)(引用屬性)

js變量可分為兩部分,基本類型和引用類型窘问。

基本類型:基本類型比較簡(jiǎn)單辆童,包括Undefined,Null,Boolean,Number,String,基本類型就是簡(jiǎn)單的數(shù)據(jù)段;
引用類型:引用類型值可能由多個(gè)值構(gòu)成惠赫,引用類型保存在內(nèi)存中把鉴,而js是不能直接訪問(wèn)內(nèi)存的,所以對(duì)于引用類型儿咱,操作的不是實(shí)際的對(duì)象庭砍,而是對(duì)對(duì)象的引用场晶。

一、簡(jiǎn)單原型鏈

function  Super(){
  this.val = 1;
  this.arr = [1];
};

function Sub(){

};

Sub.prototype = new Super();

var Sub1 = new Sub();
var Sub2 = new Sun();

Sub1.val = 5;
Sub1.arr.push(2);

alert(Sub1.val);  //5
alert(Sub2.val);  //1

alert(Sub1.arr);  //1,2
alert(Sub2.arr);  //1,2

//可以看到怠缸,修改sub1.arr后sub2.arr也變了诗轻,因?yàn)閬?lái)自原型對(duì)象的引用屬性是所有實(shí)例共享的。

如果不懂凯旭,可查看js基本類型與引用類型詳解

二概耻、借用構(gòu)造函數(shù)

function gou(val){
    console.log(typeof val);
    this.val = val;
    this.arr = [1];

    this.fun = function(){

    };
};

function fun(val){
    gou.call(this,val);
};

var fun1 = new fun(1);
var fun2 = new fun(2);
fun1.arr.push(2);

console.log(fun1.val);    //1
console.log(fun2.val);    //2

console.log(fun1.arr);    //1,2
console.log(fun2.arr);    //1

alert(sub1.fun === sub2.fun);   // false

借父類的構(gòu)造函數(shù)來(lái)增強(qiáng)子類實(shí)例,等于是把父類的實(shí)例屬性復(fù)制了一份給子類實(shí)例裝上了(完全沒(méi)有用到原型)
缺點(diǎn):
無(wú)法實(shí)現(xiàn)函數(shù)復(fù)用,每個(gè)子類實(shí)例都持有一個(gè)新的fun函數(shù)罐呼,太多了就會(huì)影響性能鞠柄,內(nèi)存爆炸。嫉柴。
P.S.好吧厌杜,剛修復(fù)了共享引用屬性的問(wèn)題,又出現(xiàn)了這個(gè)新問(wèn)題计螺。

三夯尽、組合繼承(最常用)

function zuhe(){
    this.val = 1;
    this.arr = [1];
};

zuhe.prototype.fun1 = function(){};
zuhe.prototype.fun2 = function(){};

function newSub(){
    //通過(guò)call函數(shù)繼承父類的基本數(shù)據(jù)和引用數(shù)據(jù)。
    zuhe.call(this);    //核心
};

newSub.prototype = new zuhe();
var zh1 = new newSub();
var zh2 = new newSub();

zh1.val = 2;
zh1.arr.push(2);

console.log(zh1);    //{val:2,arr:[1,2]}
console.log(zh2);    //{val:1,arr:[1]}

console.log(zh1.fun1 === zh2.fun1);  //true

把實(shí)例函數(shù)都放在原型對(duì)象上登馒,以實(shí)現(xiàn)函數(shù)復(fù)用匙握。同時(shí)還要保留借用構(gòu)造函數(shù)方式的優(yōu)點(diǎn)

四、寄生組合繼承

組合繼承是js最常用的繼承模式陈轿,組合繼承最大的問(wèn)題就是無(wú)論在什么情況下圈纺,都會(huì)調(diào)用兩次構(gòu)造函數(shù):一次是在創(chuàng)建子類型原型時(shí),另一次是在子類型構(gòu)造函數(shù)內(nèi)部麦射。

function SuperType(name){
 this.name = name;
 this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
}
 
function SubType(name, age){
 SuperType.call(this, name);  //第二次調(diào)用SuperType()
  
 this.age = age;
}
SubType.prototype = new SuperType();  //第一次調(diào)用SuperType()
SubType.prototype.sayAge = function(){
 alert(this.age);
}

在第一次調(diào)用SuperType構(gòu)造函數(shù)時(shí)蛾娶,SubType.prototype會(huì)得到兩個(gè)屬性: name和colors; 他們都是SuperType的實(shí)例屬性潜秋,只不過(guò)現(xiàn)在位于SubType的原型中蛔琅。
當(dāng)調(diào)用SubType構(gòu)造函數(shù)時(shí),又會(huì)調(diào)用一次SuperType構(gòu)造函數(shù)峻呛,這一次又在新對(duì)象上創(chuàng)建了實(shí)例屬性name和colors罗售。
于是這兩個(gè)屬性就屏蔽了原型中的兩個(gè)同名屬性。
寄生組合式繼承就是為了解決這一問(wèn)題杀饵。

function inheritPrototype (subType,superType){
    var protoType = Object.create(superType.prototype);     //創(chuàng)建對(duì)象
    protoType.constructor = subType;                        //增強(qiáng)對(duì)象
    subType.prototype = protoType;                          //指定對(duì)象
};

function SuperType(name){
    this.name = name;
    this.colors = ["red","blue","green"];
};

SuperType.prototype.sayName = function(){
    alert(this.name);
};

function SubType(name,age){
    SuperType.call(this,name);

    this.age = age;
};

inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
    alert(this.age);
};

var instance = new SubType("jack",28);
instance.sayName();         //jack
instance.sayAge();          //28

## 方法二
function beget(obj){   // 生孩子函數(shù) beget:龍beget龍莽囤,鳳beget鳳。
    var F = function(){};
    F.prototype = obj;
    return new F();
}
function Super(){
    // 只在此處聲明基本屬性和引用屬性
    this.val = 1;
    this.arr = [1];
}
//  在此處聲明函數(shù)
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
    Super.call(this);   // 核心
    // ...
}
var proto = beget(Super.prototype); // 核心
proto.constructor = Sub;            // 核心
Sub.prototype = proto;              // 核心
 
var sub = new Sub();
alert(sub.val);
alert(sub.arr);

五切距、原型式

function beget(obj){
    var F = function(){};
    F.prototype = obj;
    return new F();
};

function Super (){
    this.val = 1;
    this.arr = [1];
};

//拿到父類對(duì)象
var sup = new Super ();
//生孩子
var sub = beget(sup);
//增強(qiáng)
sub.attr1 = 1;
sub.attr2 = 2;
console.log(sub);
console.log(sub.attr1);
console.log(sub.arr);

優(yōu)點(diǎn):
從已有對(duì)象衍生新對(duì)象朽缎,不需要?jiǎng)?chuàng)建自定義類型(更像是對(duì)象復(fù)制,而不是繼承。话肖。)
缺點(diǎn):
原型引用屬性會(huì)被所有實(shí)例共享北秽,因?yàn)槭怯谜麄€(gè)父類對(duì)象來(lái)充當(dāng)了子類原型對(duì)象,所以這個(gè)缺陷無(wú)可避免無(wú)法實(shí)現(xiàn)代碼復(fù)用(新對(duì)象是現(xiàn)取的最筒,屬性是現(xiàn)添的贺氓,都沒(méi)用函數(shù)封裝,怎么復(fù)用)
P.S.這東西和繼承有很大關(guān)系嗎床蜘?為什么尼古拉斯把它也列為實(shí)現(xiàn)繼承的一種方式辙培?關(guān)系不大,但有一定關(guān)系

六邢锯、寄生式

寄生式是一種模式扬蕊,并不是只能用來(lái)繼承

function beget(obj){   // 生孩子函數(shù) beget:龍beget龍,鳳beget鳳丹擎。
    var F = function(){};
    F.prototype = obj;
    return new F();
}
function Super(){
    this.val = 1;
    this.arr = [1];
}
function getSubObject(obj){
    // 創(chuàng)建新對(duì)象
    var clone = beget(obj); // 核心
    // 增強(qiáng)
    clone.attr1 = 1;
    clone.attr2 = 2;
    //clone.attr3...
 
    return clone;
}
 
var sub = getSubObject(new Super());
alert(sub.val);     // 1
alert(sub.arr);     // 1
alert(sub.attr1);   // 1

注意:beget函數(shù)并不是必須的尾抑,換言之,創(chuàng)建新對(duì)象 -> 增強(qiáng) -> 返回該對(duì)象蒂培,這樣的過(guò)程叫寄生式繼承再愈,新對(duì)象是如何創(chuàng)建的并不重要(用beget生的,new出來(lái)的护戳,字面量現(xiàn)做的翎冲。。都可以)
優(yōu)點(diǎn):
還是不需要?jiǎng)?chuàng)建自定義類型
缺點(diǎn):
無(wú)法實(shí)現(xiàn)函數(shù)復(fù)用(沒(méi)用到原型媳荒,當(dāng)然不行)
P.S.劇情解析:有缺陷的寄生式繼承 + 不完美的組合繼承 = 完美的寄生組合式繼承府适,不妨回去找找看哪里用到了寄生

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肺樟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逻淌,老刑警劉巖么伯,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異卡儒,居然都是意外死亡田柔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門骨望,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)硬爆,“玉大人,你說(shuō)我怎么就攤上這事擎鸠∽嚎模” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)袜蚕。 經(jīng)常有香客問(wèn)我糟把,道長(zhǎng),這世上最難降的妖魔是什么牲剃? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任遣疯,我火速辦了婚禮,結(jié)果婚禮上凿傅,老公的妹妹穿的比我還像新娘缠犀。我一直安慰自己,他們只是感情好聪舒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布辨液。 她就那樣靜靜地躺著,像睡著了一般过椎。 火紅的嫁衣襯著肌膚如雪室梅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天疚宇,我揣著相機(jī)與錄音亡鼠,去河邊找鬼。 笑死敷待,一個(gè)胖子當(dāng)著我的面吹牛间涵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榜揖,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼勾哩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了举哟?” 一聲冷哼從身側(cè)響起思劳,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妨猩,沒(méi)想到半個(gè)月后潜叛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壶硅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年威兜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庐椒。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡椒舵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出约谈,到底是詐尸還是另有隱情笔宿,我是刑警寧澤犁钟,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站措伐,受9級(jí)特大地震影響特纤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜侥加,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一捧存、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧担败,春花似錦昔穴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至狈网,卻和暖如春宙搬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拓哺。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工勇垛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人士鸥。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓闲孤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親烤礁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子讼积,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • 內(nèi)容來(lái)自《JavaScript高級(jí)程序設(shè)計(jì)》第三版第6章第3節(jié) 原型鏈 ECMAScript中描述了 原型鏈的概念...
    angelwgh閱讀 238評(píng)論 0 0
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,424評(píng)論 3 12
  • 1.繼承(接口繼承和實(shí)現(xiàn)繼承) 繼承是 OO 語(yǔ)言中的一個(gè)最為人津津樂(lè)道的概念。許多 OO 語(yǔ)言都支持兩種繼承方式...
    believedream閱讀 952評(píng)論 0 3
  • 本章內(nèi)容 理解對(duì)象屬性 理解并創(chuàng)建對(duì)象 理解繼承 面向?qū)ο笳Z(yǔ)言有一個(gè)標(biāo)志脚仔,那就是它們都有類的概念勤众,而通過(guò)類可以創(chuàng)建...
    悶油瓶小張閱讀 852評(píng)論 0 1
  • 搬進(jìn)新房已經(jīng)好幾天了,每次看到寬敞的房間以及齊全的設(shè)施鲤脏,我不止一次地懷疑:難道這寬敞明亮的房間真的自己住的嗎决摧?這里...
    西瓜甜甜啦閱讀 666評(píng)論 28 30