函數(shù)的原型對象

什么是原型别智?

原型是Javascript中的繼承的繼承,JavaScript的繼承就是基于原型的繼承。

函數(shù)的原型對象

在JavaScript中,我們創(chuàng)建一個函數(shù)A(就是聲明一個函數(shù)), 那么瀏覽器就會在內(nèi)存中創(chuàng)建一個對象B,而且每個函數(shù)都默認會有一個屬性 prototype 指向了這個對象( 即:prototype的屬性的值是這個對象 )唁情。這個對象B就是函數(shù)A的原型對象疑苔,簡稱函數(shù)的原型。這個原型對象B 默認會有一個屬性 constructor 指向了這個函數(shù)A ( 意思就是說:constructor屬性的值是函數(shù)A )甸鸟。


<script>
    function Person() {
        Person.prototype.name="李五";
        Person.prototype.eat=function () {
        }
    }
    var p1=new Person()
    var p2=new Person()
    console.log(p1.name)
    console.log(p2.name)//輸出的都是李五
    //p1.name="張三" //只能改變它本身的值不能修改原型對象共享的值
    //console.log(p1.name) 輸出的是張三
    //可通過_proto_修改原型對象中的值 因為
    //console.log(Person.prototype===p1._proto_)
    //console.log(Person.prototype.constructor===Person)
    p2.__proto__.name="小吳";//修改了對象中的值 后邊輸出的都是小吳

    console.log(p1.name)
    console.log(p2.name)
</script>


說明:

  1. 從上面的圖示中可以看到惦费,創(chuàng)建p1對象雖然使用的是Person構(gòu)造函數(shù),但是對象創(chuàng)建出來之后抢韭,這個p1對象其實已經(jīng)與Person構(gòu)造函數(shù)沒有任何關(guān)系了薪贫,p1對象的[[ proto ]]屬性指向的是Person構(gòu)造函數(shù)的原型對象。
  2. 如果使用new Person()創(chuàng)建多個對象刻恭,則多個對象都會同時指向Person構(gòu)造函數(shù)的原型對象瞧省。
  3. 我們可以手動給這個原型對象添加屬性和方法,那么p1,p2,p3...這些對象就會共享這些在原型中添加的屬性和方法鳍贾。
  4. 如果我們訪問p1中的一個屬性name鞍匾,如果在p1對象中找到,則直接返回骑科。如果p1對象中沒有找到橡淑,則直接去p1對象的[[proto]]屬性指向的原型對象中查找,如果查找到則返回咆爽。(如果原型中也沒有找到梁棠,則繼續(xù)向上找原型的原型---原型鏈。 后面再講)斗埂。
  5. 如果通過p1對象添加了一個屬性name符糊,則對p1對象來說就屏蔽了原型中的屬性name。 換句話說:在p1中就沒有辦法訪問到原型的屬性name了呛凶。
  6. 通過p1對象只能讀取原型中的屬性name的值濒蒋,而不能修改原型中的屬性name的值。 p1.name = "李四"; 并不是修改了原型中的值把兔,而是在p1對象中給添加了一個屬性name沪伙。

與原型有關(guān)的幾個屬性和方法

prototype屬性
prototype 存在于構(gòu)造函數(shù)中 (其實任意函數(shù)中都有,只不過不是構(gòu)造函數(shù)的時候prototype我們不關(guān)注而已) 县好,他指向了這個構(gòu)造函數(shù)的原型對象围橡。

constructor屬性
constructor屬性存在于原型對象中,他指向了構(gòu)造函數(shù)

proto 屬性(注意:左右各是2個下劃線)
用構(gòu)造方法創(chuàng)建一個新的對象之后缕贡,這個對象中默認會有一個不可訪問的屬性 [[proto]] , 這個屬性就指向了構(gòu)造方法的原型對象翁授。

hasOwnProperty() 方法
hasOwnProperty方法拣播,可以判斷一個屬性是否來自對象本身。
hasOwnProperty這個方法可以判斷一個屬性是否在對象本身添加的收擦,但是不能判斷是否存在于原型中贮配,因為有可能這個屬性不存在。

in 操作符
in操作符用來判斷一個屬性是否存在于這個對象中塞赂。但是在查找這個屬性時候泪勒,先在對象本身中找,如果對象找不到再去原型中找宴猾。換句話說圆存,只要對象和原型中有一個地方存在這個屬性,就返回true

組合使用原型模型和構(gòu)造函數(shù)模型創(chuàng)建對象

原型模型創(chuàng)建對象的缺陷
原型中的所有的屬性都是共享的仇哆。也就是說沦辙,用同一個構(gòu)造函數(shù)創(chuàng)建的對象去訪問原型中的屬性的時候,大家都是訪問的同一個對象讹剔,如果一個對象對原型的屬性進行了修改油讯,則會反映到所有的對象上面。

使用構(gòu)造函數(shù)模型創(chuàng)建對象的缺陷
在構(gòu)造函數(shù)中添加的屬性和方法延欠,每個對象都有自己獨有的一份撞羽,大家不會共享。這個特性對屬性比較合適衫冻,但是對方法又不太合適诀紊。

使用組合模式解決上述兩種缺陷
原型模式適合封裝方法,構(gòu)造方法模式適合封裝屬性隅俘,綜合兩種模式的優(yōu)點就有了組合模式邻奠。

<script>
    function Person(name,age) {
        this.name=name;
        this.age=age;
        //屬性不共享
    }
    Person.prototype.eat=function () {
        console.log("玩"+this.name)
    }//方法共享
    Person.prototype.speak=function () {
        console.log("是"+this.age)

    }
    var p1=new Person("張三",21)
    var p2=new Person("王五",32)
    console.log(p1.name)
    p1.eat()
    console.log(p2.name)
    p1.speak()
</script>

動態(tài)原型模式創(chuàng)建對象
動態(tài)原型模式把所有的屬性和方法都封裝在構(gòu)造方法中,而僅僅在需要的時候才去在構(gòu)造方法中初始化原型为居,又保持了同時使用構(gòu)造函數(shù)和原型的優(yōu)點碌宴。

<script>
    function Person(name,age) {
        this.name=name;
        this.age=age;
        if(!Person.prototype.eat){
            Person.prototype.eat=function () {
                console.log("吃"+this.name)
            }
        }
        if(!Person.prototype.speak){
            Person.prototype.speak=function () {
                console.log("玩"+this.age)

            }
        }

    }
    var p1=new Person("a",20)
    var p2=new Person("b",30)
    console.log(p1.speak==p2.speak)//返回true
</script>

說明:

  1. 構(gòu)造函數(shù)和普通函數(shù)僅僅也僅僅是調(diào)用方式的不同。也就是說蒙畴,隨便一個函數(shù)你如果用new 的方式去使用贰镣,那么他就是一個構(gòu)造函數(shù)。
  2. 為了區(qū)別膳凝,如果一個函數(shù)想作為構(gòu)造函數(shù)碑隆,作為國際慣例,最好把這個構(gòu)造函數(shù)的首字母大寫蹬音。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末上煤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子著淆,更是在濱河造成了極大的恐慌劫狠,老刑警劉巖拴疤,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異独泞,居然都是意外死亡呐矾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門懦砂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜒犯,“玉大人,你說我怎么就攤上這事孕惜±⒀Γ” “怎么了晨炕?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵衫画,是天一觀的道長。 經(jīng)常有香客問我瓮栗,道長削罩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任费奸,我火速辦了婚禮弥激,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘愿阐。我一直安慰自己微服,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布缨历。 她就那樣靜靜地躺著以蕴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辛孵。 梳的紋絲不亂的頭發(fā)上丛肮,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天,我揣著相機與錄音魄缚,去河邊找鬼宝与。 笑死,一個胖子當(dāng)著我的面吹牛冶匹,可吹牛的內(nèi)容都是我干的习劫。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼嚼隘,長吁一口氣:“原來是場噩夢啊……” “哼榜聂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嗓蘑,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤须肆,失蹤者是張志新(化名)和其女友劉穎匿乃,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豌汇,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡幢炸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了拒贱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宛徊。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逻澳,靈堂內(nèi)的尸體忽然破棺而出闸天,到底是詐尸還是另有隱情,我是刑警寧澤斜做,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布苞氮,位于F島的核電站,受9級特大地震影響瓤逼,放射性物質(zhì)發(fā)生泄漏笼吟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一霸旗、第九天 我趴在偏房一處隱蔽的房頂上張望贷帮。 院中可真熱鬧,春花似錦诱告、人聲如沸撵枢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锄禽。三九已至,卻和暖如春箱蟆,著一層夾襖步出監(jiān)牢的瞬間沟绪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工空猜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绽慈,地道東北人。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓辈毯,卻偏偏與公主長得像坝疼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谆沃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

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