JavaScript原型詳解

1蕴忆,前言

下面是2008年Github創(chuàng)建以來,各種編程語言的排名情況


其中JavaScript自2013年之后就盤踞第一名悲幅,成為github上被使用最多的語言套鹅,早期,JS的使用還主要集中于瀏覽器中汰具,但是隨著node.js進(jìn)軍服務(wù)器開發(fā)和React Native逐漸向移動(dòng)端滲透卓鹿,一個(gè)屬于JS的全棧時(shí)代就要來臨了。而且JS界還流傳一句名言:“所有能用JS開發(fā)的應(yīng)用程序郁副,最終都會用JS來開發(fā)”减牺。我就問你怕不怕?

好了,說了這么多拔疚,我并不是想說JS為世界上最好的語言(顯然PHP才是肥隆,對吧?←_←)稚失,也不是覺得JS會替代誰栋艳,我只是覺得,JavaScript將會是一個(gè)大家(不止web端)都應(yīng)該了解和學(xué)習(xí)的語言工具句各。

2吸占,面對對象(OOP)

2.1 實(shí)現(xiàn)思路

面對對象是大家都很熟悉的程序設(shè)計(jì)思想,是對真實(shí)世界的抽象凿宾,目前主要OOP語言用來實(shí)現(xiàn)面對對象的基礎(chǔ)是類矾屯,通過類的封裝,繼承來映射真實(shí)世界初厚。包括Java件蚕,C#,甚至是python等都通過類的設(shè)計(jì)來實(shí)現(xiàn)面對對象产禾。但是細(xì)想起來也會覺得有問題排作,因?yàn)檎鎸?shí)世界其實(shí)沒有類這種概念,只有一個(gè)個(gè)不同的對象亚情,真實(shí)世界中妄痪,繼承關(guān)系發(fā)生在對象和對象之間,而不是類楞件。就比如孩子是對象衫生,父母也是對象,孩子(對象)繼承自父母(對象)

JS也是面對對象的編程語言土浸,只不過它實(shí)現(xiàn)面對對象的思路是基于原型(prototype),而不是類障簿。這種思路也叫對象關(guān)聯(lián)(Object Link Other Object),即在對象上直接映射那種真實(shí)世界的關(guān)系(如繼承)栅迄。

2.2 原型概念

相關(guān)的概念其實(shí)我研究了好幾天,除開原型概念本身皆怕,與之聯(lián)系的對象的產(chǎn)生毅舆,構(gòu)造函數(shù),proto,prototype的區(qū)別愈腾,為什么對象沒有prototype這個(gè)指向原型的屬性,而是使用proto來指向原型憋活?

好,我們先來談?wù)勗瓦@個(gè)概念虱黄。JS中一切皆對象悦即,而每個(gè)對象都有一個(gè)原型(Object除外),這個(gè)原型,大概就像Java中的父類辜梳,所以粱甫,基本上你可以認(rèn)為原型就是這個(gè)對象的父對象,即每一個(gè)對象(Object除外)內(nèi)部都保存了它自己的父對象作瞄,這個(gè)父對象就是原型茶宵。一般創(chuàng)建的對象如果沒有特別指定原型,那么它的原型就是Object(這就很類似Java中所有的類默認(rèn)繼承自O(shè)bject類)宗挥。

2.3 對象創(chuàng)建

在JS中乌庶,對象創(chuàng)建的方法有很多種,最常見的如下:

//第一種契耿,手動(dòng)創(chuàng)建

var a={'name':'lala'}; ??


//第二種瞒大,構(gòu)造函數(shù)

function A(){

? ? this.name='lala';

}

var a=new A();


//第三種,class (ES6標(biāo)準(zhǔn)寫法)


class A{

? ? constructor(){

? ? ? ? //super();此處沒有使用extends顯式繼承搪桂,不可使用super()

? ? ? ? this.name='lala';

? ? }

}

var a=new A()

//其實(shí)后面兩種方法本質(zhì)上是一種寫法

這三種寫法創(chuàng)建的對象的原型(父對象)都是Object,需要提到的是透敌,ES6通過引入class ,extends等關(guān)鍵字,以一種語法糖的形式把構(gòu)造函數(shù)包裝成類的概念锅棕,更便于大家理解拙泽。是希望開發(fā)者不再花精力去關(guān)注原型以及原型鏈,也充分說明原型的設(shè)計(jì)意圖和類是一樣的裸燎。

2.3 查看對象原型

當(dāng)對象被創(chuàng)建之后顾瞻,查看它們的原型的方法不止一種,以前一般使用對象的proto屬性德绿,ES6推出后荷荤,推薦用Object.getPrototypeOf()方法來獲取對象的原型

function A(){

? ? this.name='lala';

}

var a=new A();

console.log(a.__proto__) ?

//輸出:Object {}


//推薦使用這種方式獲取對象的原型

console.log(Object.getPrototypeOf(a)) ?

//輸出:Object {}

無論對象是如何創(chuàng)建的,默認(rèn)原型都是Object移稳,在這里需要提及的比較特殊的一點(diǎn)就是蕴纳,通過構(gòu)造函數(shù)來創(chuàng)建對象,函數(shù)A本身也是一個(gè)對象个粱,而A有兩個(gè)指向表示原型的屬性古毛,分別是proto和prototype,而且兩個(gè)屬性并不相同

function A(){

? ? this.name='lala';

}

var a=new A();

console.log(A.prototype) ?

//輸出:Object {}


console.log(A.__proto__) ?

//輸出:function () {}

console.log(Object.getPrototypeOf(A))

//輸出:function () {}

函數(shù)的的prototype屬性只有在當(dāng)作構(gòu)造函數(shù)創(chuàng)建的時(shí)候都许,把自身的prototype屬性值賦給對象的原型稻薇。而實(shí)際上,作為函數(shù)本身胶征,它的原型應(yīng)該是function對象塞椎,然后function對象的原型才是Object。

總之睛低,建議使用ES6推薦的查看原型和設(shè)置原型的方法案狠。

2.4 原型的用法

其實(shí)原型和類的繼承的用法是一致的:當(dāng)你想用某個(gè)對象的屬性時(shí)服傍,將當(dāng)前對象的原型指向該對象,你就擁有了該對象的使用權(quán)了骂铁。

function A(){

? ? this.name='world ';

}

function B(){

? ? this.bb="hello"

? ? }

var a=new A();

var b=new B();


Object.setPrototypeOf(a,b);

//將b設(shè)置為a的原型,此處有一個(gè)問題吹零,即a的constructor也指向了B構(gòu)造函數(shù),可能需要糾正

a.constructor=A;

console.log(a.bb)

//輸出 hello

增補(bǔ))


如果使用ES6來做的話則簡單許多从铲,甚至不涉及到prototype這個(gè)屬性

class B{

? ? ?constructor(){


? ? ? ? this.bb='hello'

? ? ?}

}

class A ?extends B{

? ? ?constructor(){

? ? ? ? super()

? ? ? ? this.name='world'

? ? ?}

}


var a=new A();

console.log(a.bb+" "+a.name);

//輸出hello world



console.log(typeof(A))

//輸出 ?"function"

怎么樣瘪校?是不是已經(jīng)完全看不到原型的影子了?活脫脫就是類繼承名段,但是你也看得到實(shí)際上類A 的類型是function阱扬,所以說,本質(zhì)上class在JS中是一種語法糖伸辟,JS繼承的本質(zhì)依然是原型麻惶,不過,ES6引入class信夫,extends 來掩蓋原型的概念也是一個(gè)很友好的舉動(dòng)窃蹋,對于長期學(xué)習(xí)那些類繼承為基礎(chǔ)的面對對象編程語言的程序員而言。

我的建議是静稻,盡可能理解原型警没,盡可能用class這種語法糖。

2.5 原型鏈

這個(gè)概念其實(shí)也變得比較簡單振湾,可以類比類的繼承鏈條杀迹,即每個(gè)對象的原型往上追溯,一直到Object為止押搪,這組成了一個(gè)鏈條树酪,將其中的對象串聯(lián)起來,當(dāng)查找當(dāng)前對象的屬性時(shí)大州,如果沒找到续语,就會沿著這個(gè)鏈條去查找,一直到Object厦画,如果還沒發(fā)現(xiàn)疮茄,就會報(bào)undefined。那么也就意味著你的原型鏈不能太長根暑,否則會出現(xiàn)效率問題娃豹。

3,總結(jié)


對于原型概念的理解

類比類的繼承购裙,對象的原型可以理解為對象的父對象



原型的運(yùn)用

盡可能使用ES6的標(biāo)準(zhǔn),使用class鹃栽,extends,Object.getPrototype(),Object.setPrototype()等等



需要注意的點(diǎn)

原型繼承鏈條不要太長

指定原型時(shí)躏率,注意constructor也會改變躯畴。


需要上圖完整資料或者更多Java全套視頻的可以添加裙;712352051 小編不看大家技術(shù)怎么樣 來的都?xì)g迎薇芝,包括小編最近整理的一套資料都可以分享給大家的
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蓬抄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子夯到,更是在濱河造成了極大的恐慌嚷缭,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耍贾,死亡現(xiàn)場離奇詭異阅爽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)荐开,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門付翁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晃听,你說我怎么就攤上這事百侧。” “怎么了能扒?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵佣渴,是天一觀的道長。 經(jīng)常有香客問我初斑,道長辛润,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任越平,我火速辦了婚禮频蛔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秦叛。我一直安慰自己晦溪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布挣跋。 她就那樣靜靜地躺著三圆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪避咆。 梳的紋絲不亂的頭發(fā)上舟肉,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音查库,去河邊找鬼路媚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛樊销,可吹牛的內(nèi)容都是我干的整慎。 我是一名探鬼主播脏款,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼裤园!你這毒婦竟也來了撤师?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拧揽,失蹤者是張志新(化名)和其女友劉穎剃盾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淤袜,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痒谴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饮怯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闰歪。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蓖墅,靈堂內(nèi)的尸體忽然破棺而出库倘,到底是詐尸還是另有隱情,我是刑警寧澤论矾,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布教翩,位于F島的核電站,受9級特大地震影響贪壳,放射性物質(zhì)發(fā)生泄漏饱亿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一闰靴、第九天 我趴在偏房一處隱蔽的房頂上張望彪笼。 院中可真熱鬧,春花似錦蚂且、人聲如沸配猫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泵肄。三九已至,卻和暖如春淑翼,著一層夾襖步出監(jiān)牢的瞬間腐巢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工玄括, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冯丙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓遭京,卻偏偏與公主長得像银还,于是被迫代替她去往敵國和親风宁。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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