成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

原型鏈?zhǔn)鞘裁??關(guān)于原型鏈中constructor、prototype及__proto__之間關(guān)系的認(rèn)

kaka / 2480人閱讀

摘要:的隱式原型是母,母是由構(gòu)造函數(shù)構(gòu)造的,但函數(shù)的隱式原型又是。。。。可能是考慮到它也是由構(gòu)造函數(shù)生成的吧,所以返回的值也是。

首先,我們暫且把object類型和function類型分開來,因?yàn)?function是一個特殊的對象類型,我們這里這是便于區(qū)分,把function類型多帶帶拿出來。順便一提,typeof也是多帶帶把function設(shè)為一種類型,我們可以用typeof來驗(yàn)證我們的猜想。

從上圖中可以看到,所有的橘色箭頭(constructor)都指向function Function(){},所有的黑色箭頭(__proto__)開始有兩條路可以走,但是最后都匯聚在了一起,指向null。而天藍(lán)色箭頭(prototype)不具有連續(xù)性,一般都是一個function指向一個object。然后我們可以得出以下結(jié)論:

所有對象的構(gòu)造函數(shù)(constructor)最終指向function Function( ){ }這個函數(shù),包括他自己。ps:為了方便,我們稱它為母Function。

所有對象的__proto__最終指向null,即一切原型鏈的末端就是null。

所謂的一切源于對象,這里的”對象”指的是Object{}(紅色虛線框內(nèi),也就是Object的prototype)。ps:為了方便,我們在這里叫它母Object。

除了Object的原型(prototype)直接指向母Object,其他所有類型的(構(gòu)造器的)原型(prototype)都先指向一個由母Object派生出來的一個子Object,再指向母Object,F(xiàn)unction的原型為function{}。ps:構(gòu)造器,即構(gòu)造函數(shù)。

哲學(xué)部分:這幅圖包含兩個”先有雞還是先有蛋”的問題:

function(){}是由母Function構(gòu)造的,但它同時又是母Function的原型。。

function(){}的隱式原型(__proto__)是母Object,母Object是由構(gòu)造函數(shù) function Object(){}構(gòu)造的,但函數(shù)function Object(){}的隱式原型又是function (){}。。。。
當(dāng)然除了”先有雞還是先有蛋”,原型鏈中還有一個最最有哲理的問題:

構(gòu)造函數(shù)function Function(){}的構(gòu)造函數(shù)就是他自己,就是說,他自己把自己生下來了。。。。。 = =

至于為什么function(){}有倆個框框,其實(shí)是因?yàn)樗窃椭凶钐厥獾?。它是原型中唯一一個的function類型的,其他的原型都是object類型。可能是考慮到它也是由構(gòu)造函數(shù)Function生成的吧,所以typeof返回的值也是function。

我們再來說一下可能大家都很疑惑的問題,就是原型(prototype)和隱式原型(__proto__)的區(qū)別。

我說一下我的見解。相對于”原型”,我覺得”__proto__”更適合叫做父對象,因?yàn)樵谠玩溨?,?fù)責(zé)連接各個對象的,就是”__proto__”。也就是說,我改寫對象的”prototype”,并不會影響對象在原型鏈中的位置,想脫離或者改變原型鏈,只能是改寫”__proto__”。

在原型鏈中,對象和它的”__proto__”指向的對象的關(guān)系,更像是別的語言中的子類和父類。子類會繼承父類的方法和屬性,而且會和父類保持一樣的類型。

一般來說,”__proto__”都是指向某一個對象的”prototype”屬性,所以對象會繼承的也就是其父對象”prototype”中的屬性和方法,但是并不會繼承其父對象自身的屬性方法。說的可能有點(diǎn)繞,我們舉個栗子:

//以O(shè)bject為原型創(chuàng)建一個對象,obj。
var obj=new Object
/*這句話可以翻譯為:
var obj={}
obj.__proto__=Object.prototype
*/

這個時候,obj的”__proto__”指向的是Object.prototype,所以obj的父對象是Object.prototype,obj會繼承Object.prototype中的屬性方法,但是并不會繼承Object中的屬性和方法。這時候我們用obj.toString()是可以的,但是用obj.length就會報錯。這是因?yàn)閠oString()是寫在Object.prototype里面的,而length是寫在Object里面的。
在學(xué)習(xí)運(yùn)算符的時候,相比很多初學(xué)者也會有和我一樣的疑問,為什么instanceof向上查找會在prototype里查找,而不在”父對象”中查找。理解我上面所說,大家相比也會明白了吧。就拿上面的例子來說,其實(shí)Object只是obj的構(gòu)造器,構(gòu)造函數(shù)而已,obj真正的父對象是Object.prototype。
那講到這里有的小伙伴就會有疑問了,那我要是想繼承Object里面的屬性怎么辦?其實(shí)也很簡單,設(shè)置obj的”__proto__”指向Object就可以了。不過有一點(diǎn),”__proto__”屬性畢竟是底杠開頭,是官方不想暴露在外面的屬性,能不用的時候最好不要用。其實(shí)就算不用”__proto__”也是可以達(dá)到想要的效果的。Object里面有一個可以創(chuàng)建對象的方法create,用它我們可以輕松達(dá)到我們的要求。舉個栗子:

//以O(shè)bject為原型創(chuàng)建一個對象,obj。
var obj= Object.create(Object)
/*這句話可以翻譯為:
var obj={}
obj.__proto__=Object
再說一下create的用法:
Object.create(prototype,[{code}]);//返回一個對象
可以看到,這里有兩個參數(shù),第一個參數(shù)prototype相當(dāng)于創(chuàng)建對象的__proto__,值得話隨便一個對象就可以了,第二個參數(shù)可以不填,里面詳細(xì)寫創(chuàng)建對象的一些屬性和他們的屬性標(biāo)簽。注意,create創(chuàng)建的是一個對象,和new一樣,無論以什么為父對象,返回值都是object。
*/

再來說說prototype,通過上圖大家會發(fā)現(xiàn),prototype屬性只是一個函數(shù)和一個對象之間的一個橋梁,在這里為什么要說是橋梁呢,為什么不說是函數(shù)的一個屬性呢?我曾寫過一個例子:

function fa(){}
fa.prototype.fname=’fa’
var ch=new fa()
ch.fname        //’fa’
fa.prototype={fname:’newfa’} //改寫prototype
ch.fname        //依舊是’fa’,
ch.hasOwnProporty(‘fname’)    //false
ch.__proto__==fa.prototype    //false

通過上述代碼大家可以看出來了吧,ch繼承fa時只是讓ch.__proto__指向了fa.prototype指向的地址,而不是指向fa.prototype。所以就導(dǎo)致了改寫fa.prototype并不會影響ch.fname的值。改寫后ch.__proto__不等于fa.prototype了,也就是說ch和fa已經(jīng)半毛錢關(guān)系都沒有了。
基本上到這里,大家都會對原型鏈有一定的認(rèn)識了,至于對象中的特殊存在——function,大家可以自己去探索一下。以上都是自己對于JS中原型鏈的認(rèn)識,如有錯誤歡迎大家指正~
ps:sf的編排好難用 !

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79872.html

相關(guān)文章

  • 理解javaScript原型原型

    摘要:構(gòu)造函數(shù)的屬性指向原型對象原型對象的屬性指向構(gòu)造函數(shù)實(shí)例對象的指向原型對象所有引用類型默認(rèn)都繼承了,而這個繼承也是通過原型鏈實(shí)現(xiàn)的。第一種方式是使用操作符,只要用這個操作符來測試實(shí)例與原型鏈中出現(xiàn)過的構(gòu)造函數(shù),結(jié)果就會返回。 理解對象 首先對象的定義是:無序?qū)傩缘募?,其屬性可以包含基本值、對象或者函?shù)。嚴(yán)格來講,這就相當(dāng)于說對象是一組沒有特定順序的值。對象的每個屬性或方法都有一個名...

    NSFish 評論0 收藏0
  • 原型

    摘要:不過,從編程習(xí)慣上,我們應(yīng)該盡量讓對象的指向其構(gòu)造函數(shù),以維持這個慣例總結(jié)原型和原型鏈?zhǔn)菍?shí)現(xiàn)繼承的一種模型原型鏈?zhǔn)强啃纬傻?,它在其中的作用屬于連接的線 原型鏈概念 每個構(gòu)造函數(shù)內(nèi)部都會有一個(constructor,prototype原型對象),而且都會有一個內(nèi)置樹形__proto__屬性用于指向創(chuàng)建它函數(shù)對象的prototype原型,當(dāng)然原型對象也會有__proto__屬性,源源不斷...

    gaomysion 評論0 收藏0
  • JavaScript進(jìn)階 - 1. 原型原型鏈的概念

    摘要:對應(yīng)的關(guān)系圖如下講解了構(gòu)造函數(shù)和原型對象之間的關(guān)系,那么實(shí)例對象和原型對象之間的關(guān)系又是怎么樣的呢下面講解。原型對象的指向的是構(gòu)造函數(shù)和本身沒有屬性,但是其原型對象有該屬性,因此也能獲取到構(gòu)造函數(shù)。 JavaScript進(jìn)階 - 1. 原型和原型鏈的概念 我們好多經(jīng)常會被問道JavaScript原型和原型鏈的概念,還有關(guān)于繼承,new操作符相關(guān)的概念。本文就專門整理了原型和原型鏈的概念...

    elisa.yang 評論0 收藏0
  • JS原型

    摘要:構(gòu)造函數(shù)除了以指定模式創(chuàng)建對象之外,構(gòu)造函數(shù)也做了另一個有用的事情它自動地為新創(chuàng)建的對象設(shè)置一個原型對象。正式來說,如果思考一下分類的概念并且我們已經(jīng)對進(jìn)行了分類,那么構(gòu)造函數(shù)和原型對象合在一起可以叫作類。 這篇文章是「深入ECMA-262-3」系列的一個概覽和摘要。每個部分都包含了對應(yīng)章節(jié)的鏈接,所以你可以閱讀它們以便對其有更深的理解。 對象 ECMAScript做為一個高度抽象的面...

    neuSnail 評論0 收藏0
  • 「譯文」JavaScript核心

    摘要:在這個情況下我們可能需要使用構(gòu)造函數(shù),其以指定的模式來創(chuàng)造對象。構(gòu)造函數(shù)也有自己的,值為,也通過其屬性關(guān)聯(lián)到。從邏輯上來說,這是以棧的形式實(shí)現(xiàn)的,它叫作執(zhí)行上下文棧。 原文:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/ 對象 原型鏈 構(gòu)造函數(shù) 執(zhí)行上下文棧 執(zhí)行上下文 變量對象 活動對象 作用域鏈 閉包 Thi...

    高璐 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<