Day04(原型對象,面向對象繼承鳄逾,原型鏈)

原型對象

Javascript稻轨,萬事萬物皆對象;
但是呢雕凹,對象也是有區(qū)別滴殴俱,它分為普通對象和函數(shù)對象;
也就是object和function枚抵;

什么是原型對象线欲?

在javascript中,每當定義一個對象的時候汽摹,對象都會包含一些自帶的屬性李丰,
其中,每一個函數(shù)對象都有一個屬性:prototype屬性逼泣,這個屬性趴泌,就是指向函數(shù)的原型對象。
在JS里面拉庶,每一個對象踱讨,都有proto屬性,但是只有函數(shù)對象砍的,才有prototype屬性;
原型對象和普通對象莺治,沒啥區(qū)別廓鞠,只要記住原型對象就是:
構造函數(shù).prototype={}
也就是說,原型對象(person.prototype)就是構造函數(shù)(person)的一個實例

__ proto__

JS在創(chuàng)建對象的時候谣旁,都有一個叫做proto的內置屬性床佳,用于指向創(chuàng)建他的構造函數(shù)的原型對象;

image.png

通過這個連接圖榄审,我們可以看到

Person.prototype.constructor = Person砌们;    //構造函數(shù)的指針指向他自己
person1._proto_ == Person.prototype;     //實例對象的_proto_就是構造函數(shù)的原型對象
person1.constructor == Person;    //實例對象的指針搁进,是指向構造函數(shù)浪感;

那么,這個連接鏈饼问,它的重點是:他是存在于 “實例和構造函數(shù)的原型” 之間影兽,而不是存在于 “實例和構造函數(shù)” 之間;

在javascript里面莱革,創(chuàng)建對象有兩種方法:
var obj = {};字面量
var obj = new Object();和上面完全相同

那么obj就是構造函數(shù)的一個實例峻堰,所以

obj.constructor ===Object;
obj._proto_ ===Object.prototype;
也就是說讹开,我們實例化的obj變量(實例化對象),他的指針捐名,指向object這個構造函數(shù)
他的我_proto_指向Object的原型對象旦万;
我們用來創(chuàng)建對象的構造函數(shù)又稱之為構造器;

面向對象繼承

第一種方法
/*第一個方法镶蹋,構造函數(shù)的綁定成艘,也是最簡單的方法*/
/*使用call或者apply方法,將父對象的構造函數(shù)綁定在子對象上梅忌, 那么就在子對象加一句話就可以了*/

function Xs(){
    this.type = "學生";
}
function Dxs(name,age){
    Xs.apply(this,arguments);
    this.name = name;
    this.age = age;             
}
            
var mmm = new Dxs("某某某",18);
console.log(mmm.type);
第二種方法(常用)
function Xs(){
    this.type = "學生";
}
function Dxs(name,age){
    this.name = name;
    this.age = age;             
}
            
Dxs.prototype = new Xs();
//將我們的Dsx的prototype對象指向Xs的實例狰腌,它會刪除prototype對象原本的值,并且賦予一個新值(就是替換)
Dxs.prototype.constructor = Dxs();
console.log(Dxs.prototype.constructor==Dxs)牧氮;

//任何一個prototype對象琼腔,都有一個constructor屬性,這個屬性指向他的構造函數(shù)踱葛,前面提到過丹莲,這是一個指針,把prototype指向Dxs尸诽;
//如果沒有Dxs.prototype = new Xs();這一行代碼甥材,Dsx.prototype.constructor指向誰?指向大學生
//但是性含,我們加入Dxs.prototype = new Xs();這一行后洲赵,Dxs的prototype是不是指向Xs,那么這個constructor指針是不是指向Xs
//也就是說商蕴,我們直接使用prototype繼承叠萍,會導致繼承鏈非常混亂绪商,那么我們必須手動糾正回來
//必須必須必須注意苛谷,在編程的過程中,務必遵循格郁,如果替換了prototype對象腹殿,
//那么,下一步必須給這個prototype對象添加上constructor屬性例书,并指回原本自己的構造函數(shù)锣尉;
                        
var mmm = new Dxs("某某某",18);
console.log(mmm.type);
第三種方法
function Xs(){}
Xs.prototype.type = "學生";
            
function Dxs(name,age){
    this.name = name;
    this.age = age;             
}
            
Dxs.prototype = Xs.prototype;
Dxs.prototype.constructor = Dxs;
            
Dxs.prototype.type = "大學生";
var mmm = new Dxs("某某某",18);
console.log(Xs.prototype.type);

/*優(yōu)點:效率比較高,不用創(chuàng)建Xs的實例對象决采,比較省內存*/
/*缺點:Dxs.prototype和Xs的prototype現(xiàn)在指向了同一個對象了*/

/*Dxs.prototype.type = '大學生';
console.log(Xs.prototype.type);*/
//所以悟耘,這個方法是有問題的,問題出在哪兒织狐?
//Dxs.prototype.constructor = Dxs;
//這一行代碼暂幼,把Xs.prototype對象的constructor屬性也給改掉了
第四種方法:利用空對象最為中介(常用)
function Xs(){}
Xs.prototype.type = "學生";
            
function Dxs(name,age){
    this.name = name;
    this.age = age;             
}
            
//Dxs.prototype = new Kong();
//Dxs.prototype.constructor = Dxs;

function extend(Child,Parent){
    var Kong = function(){};
    Kong.prototype = Xs.prototype;
    Child.prototype = new Kong();
    Child.prototype.constructor = Child;
                
    Child.end = Child.prototype;
    //意思筏勒,為子對象設置一個end屬性,這個屬性指向父對象的prototype屬性旺嬉,end(自定義屬性)是“向上”管行、“上一層”的意思
    //這個就相當于給子對象開了一條路,可以直接調用父對象方法邪媳,在這里只是為了實現(xiàn)繼承的完整性捐顷,屬于備用性質,
    //因為子對象繼承的是空對象雨效,所以要通過這行代碼才能調用得到父對象迅涮;              
}
            
extend(Dxs,Xs);
var mmm = new Dxs("某某某",18);
console.log(mmm.type);
第五種方法:克隆
function extend(Child,Parent){
    var p = Parent.prototype;
    var c = Child.prototype;
    for(var i in p){
        c[i]=p[i];
    }
    c.uber = p;
}
        
function Xs(){}
Xs.prototype.type = '學生';
        
function Dxs(name,age){
    this.name = name;
    this.age = age;
}
        
extend(Dxs,Xs);
var wzq = new Dxs('吳澤權',18)
alert(wzq.type);

原型鏈

function Person(name,age){
            this.name = name;
            this.age = age;
        }
        var p1 = new Person('吳澤權',19);
        
        //p1._proto_是什么東西?
        //是不是Person.prototype徽龟;
        /*因為實例對象._proto_等于構造函數(shù)的原型對象*/
        /*也就是說叮姑,p1._proto_等于Person.prototype*/
        /*__proto__每一邊有兩個下劃線*/
        console.log(p1.__proto__ === Person.prototype)//true
        
        
        //Person.__proto__又是什么?
        //前面說過据悔,實例對象的__proto__等于構造函數(shù)的prototype
        //因為Person是通過function來寫出來的
        //也就是說传透,Person是通過new Function來構造出來的實例對象;
        //Person.__proto__===Function.prototype;
        console.log(Person.__proto__==Function.prototype);
        
        //Person.prototype.__proto__又是什么呢极颓?
        //前面說過朱盐,對象分為函數(shù)對象和普通對象,prototype他不是函數(shù)對象菠隆,他只是函數(shù)對象衍生的普通對象
        //普通對象就是由Object構造的
        //那么Person.prototype.__proto__就是等于Object.prototype
        console.log(Person.prototype.__proto__==Object.prototype)
        
        //Object.__proto__又是什么兵琳?
        //和第二題一樣,不論是Object還是Function骇径,都是通過函數(shù)構造的
        console.log(Object.__proto__==Function.prototype);
        
        //Object.prototype.__proto__又是什么呢闰围?
        //記住,Object對象的原型對象既峡,已經(jīng)是處于原型鏈的頂端了,頂端沒有東西了啊碧查,所以是null
        console.log(Object.prototype.__proto__==null)

前面說過运敢,所有的函數(shù)對象的__proto__(原型)都指向Function.prototype
在JS里面,有十多個構造器:例如Number忠售、Object传惠、Array、Date;
他們這些構造器的原型都是Function.prototype

而Math稻扬、JSON是以對象的形式存在卦方,不需要new就可以聲明,所以他們的原型(__proto__)就是Object.prototy泰佳;

也就是說:
所有的構造器都來自Function.prototype盼砍,甚至包括根構造器Object以及Function自身尘吗,也就是說,所有的構造器都繼承了Function.prototype的屬性以及方法浇坐,比如說length睬捶、call、apply

也就是說近刘,構造器的__proto__就是Function.prototype擒贸,那么Function.prototype的原型(__proto__)又是誰呢?

在Javascript里面觉渴,函數(shù)是一等公民
也就是說介劫,所有的構造器也都是一個普通的JS對象,同時它也繼承了Object.prototype上面的所有方法:toString,valueOf
Object.protot又是誰呢案淋?
已經(jīng)到頂了座韵,就是null

之前學習Js,可以使用很多內置方法
parseInt()哎迄、toString()回右,都可以使用,為什么可以使用呢漱挚?
因為翔烁,當我們創(chuàng)建一個函數(shù)的時候,
var peoson = new Object()旨涝;
person是Object的實例蹬屹,所以繼承了Object.prototype的所有方法
例如,當我們創(chuàng)建一個數(shù)組的時候白华,是不是數(shù)組就繼承了Array.prototype上面的所有方法慨默,所以我們之所以能用那么多的方法,就是因為繼承

console.log(Date.__proto__==Function.prototype);
console.log(Math.__proto__==Object.prototype);
console.log(Function.prototype.__proto__==Object.prototype);
console.log(Object.prototype)
console.log(Array.prototype)
var num = [1,2,3,]
console.log(num.hasOwnProperty())

/*雖然Array.prototype沒有hasOwnProperty()這個方法弧腥,但是他有原型厦取,他的原型是不是__proto__*/
//Array()是繼承自Object,那么Array.__proto__==Object.prototype
/*所以,當你使用num.hasOwnProperty()的時候,JS會先找到他的構造函數(shù)(Array)的原型對象Array.prototype,看下他有沒有hasOwnProperty()
沒有的話,一路按照原型對象找下去,下一步就是找Arry.prototype的原型對象,那么就是找Array.prototype.__proto__*/

總結:

原型和原型鏈是JS實現(xiàn)繼承的一種模型
原型鏈的形成管搪,真正是靠的__proto__,而不是prototype虾攻;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市更鲁,隨后出現(xiàn)的幾起案子霎箍,更是在濱河造成了極大的恐慌,老刑警劉巖澡为,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漂坏,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機顶别,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門谷徙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人筋夏,你說我怎么就攤上這事蒂胞。” “怎么了条篷?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵骗随,是天一觀的道長。 經(jīng)常有香客問我赴叹,道長鸿染,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任乞巧,我火速辦了婚禮涨椒,結果婚禮上,老公的妹妹穿的比我還像新娘绽媒。我一直安慰自己蚕冬,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布是辕。 她就那樣靜靜地躺著囤热,像睡著了一般。 火紅的嫁衣襯著肌膚如雪获三。 梳的紋絲不亂的頭發(fā)上旁蔼,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音疙教,去河邊找鬼棺聊。 笑死,一個胖子當著我的面吹牛贞谓,可吹牛的內容都是我干的限佩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼裸弦,長吁一口氣:“原來是場噩夢啊……” “哼祟同!你這毒婦竟也來了?” 一聲冷哼從身側響起烁兰,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎徊都,沒想到半個月后沪斟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年主之,在試婚紗的時候發(fā)現(xiàn)自己被綠了择吊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡槽奕,死狀恐怖几睛,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情粤攒,我是刑警寧澤所森,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站夯接,受9級特大地震影響焕济,放射性物質發(fā)生泄漏。R本人自食惡果不足惜盔几,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一晴弃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逊拍,春花似錦上鞠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至注整,卻和暖如春能曾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肿轨。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工寿冕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人椒袍。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓驼唱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親驹暑。 傳聞我的和親對象是個殘疾皇子玫恳,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容