javascript原型詳解

相信很多人都很困惑于javascript的原型系統(tǒng)蹬癌,佑稠,在我剛開始接觸javascript的原型系統(tǒng)的時候,我也非常困惑于它的結構屋确,因為我以前都沒有接觸過這種基于原型的語言。javascript是一個基于原型的語言续扔,雖然是以函數(shù)為第一等公民的語言攻臀,但也可以實現(xiàn)面向?qū)ο螅蔷褪腔谒脑拖到y(tǒng)纱昧。

javascript原型之函數(shù)

現(xiàn)在我們來寫一個函數(shù)

function A(){

}

這是一個內(nèi)容為空的函數(shù)刨啸,但它真的內(nèi)容為空嗎?讓我們來看下面一段代碼

function A(){

}

console.log(A.toString());;//輸出為function A() {}

我們知道识脆,javascript里面的一切都是對象设联,函數(shù)也是,既然函數(shù)是對象那么就可以調(diào)用函數(shù)對象的方法灼捂,所以我試著調(diào)用了toString 方法离例,它輸出了一個字符串,證明toString方法是存在的悉稠。那么toString 方法到底是存在在那里呢宫蛆,不存在于函數(shù)體里,那么存在一個地方必然有toString的函數(shù)體且對象function A以某種方式獲得了toString方法的調(diào)用權的猛。耀盗。想虎。

我百度了一下基于原型的語言的特征,基于原型的語言叛拷,必然有一個或著多個最初的對象舌厨,然后以后的對象都是由這些最初對象克隆過來的,也就是說胡诗,基于原型的語言中對象的生成是根據(jù)存在的對象來復制的邓线。

好,那我們開始下一步的實驗

function A(){

}
console.log(A.__proto__);//Function
console.log(A.prototype);//{}

我輸出了Javascript對象所擁有的兩個屬性煌恢,這是javascript語言規(guī)定的兩個屬性_proto_屬性指向?qū)ο髽嬙旌瘮?shù)的原型(不是很理解)骇陈,prototype屬性指向?qū)ο蟮脑汀慕Y果看A函數(shù)構造函數(shù)的原型是Function,A函數(shù)自己的原型是{ }(同樣不是很理解)

于是我又做了下面這個實驗

Function.prototype.getName = function(){
    return "FunctionTest";
}

function A(){

}
console.log(A.__proto__ === Function.prototype);//true
console.log(A.getName());//FunctionTest

function B(){

}
console.log(B.__proto__ === Function.prototype);//true
console.log(B.getName());//FunctionTest

console.log(A.__proto__ === A.constructor.prototype);//true
//即函數(shù)作為對象它的構造函數(shù)為Function

我從另外的地方得知javascript里面有內(nèi)建的Function和Object對象瑰抵,于是我想著Function對象是否和function A 有些關聯(lián)呢你雌,當我看到第一條console.log語句返回true的時候,我知道我是正確的二汛,于是我擴展了Function.prototype 給其中添加了getName方法婿崭,然后我在用函數(shù)A調(diào)用了這個方法返回FunctionTest,我又新建了函數(shù)B,也調(diào)用了這個方法肴颊,返回FunctionTest氓栈。

至此我知道了函數(shù)_proto屬性的指向,指向其構造函數(shù)的原型婿着,當對象A調(diào)用getName函數(shù)的時候授瘦,由于A對象沒有getName函數(shù),javascript會尋找對象A的_proto屬性所對應對象竟宋,有則調(diào)用提完,沒有則繼續(xù)向上找。

函數(shù)的prototype屬性我一開始始終沒有找到與之對應的對象

console.log(A.prototype === Function.__proto__);//false
console.log(A.prototype === Function.prototype);//false
console.log(A.prototype === Object.__proto__);//false
console.log(A.prototype === Object.prototype);//false

后來我換了一種思考方式終于找到了

console.log(A.prototype.__proto__ === Object.prototype);//true
console.log(A.prototype.prototype);//undefined

而之后我又實驗了

console.log(Function.prototype.__proto__ === Object.prototype);

所以最終所有的一切對象的內(nèi)置函數(shù)比如toString都是在Object.prototype里的

然后我又有一個猜測
所有一切函數(shù)對象的內(nèi)置函數(shù)比如call,apply都是Function.prototype里的丘侠,可以很容易的就驗證徒欣,普通對象是不能調(diào)用call,apply的。

javascript原型之對象

我實驗了如下的代碼

function A(){
    this.getText = function(){
        return "Text";
    }
}

A.prototype.getName = function(){
    return "my god";
}

var i = new A();

console.log(i.getText());//Text
console.log(i.getName());//my god

然后我改了一下程序

function A(){
    this.getName = function(){
      return "Text";
    }
}

A.prototype.getName = function(){
    return "my god";
}

var i = new A();

console.log(i.getName());//Text
console.log(i.__proto__ === A.prototype);//true
console.log(i.prototype);//undefined

由上面的實驗可知蜗字,由函數(shù)A作為構造函數(shù)打肝,所克隆出來的普通對象i的_proto_屬性指向函數(shù)A的原型(也就是prototype屬性),且普通對象i的prototype屬性是沒有定義的挪捕。

當i調(diào)用getName函數(shù)時闯睹,由于i是由函數(shù)A克隆出來(大家還沒忘記原型語言的特征吧,就是新的對象是由另一個已存在的對象克隆的)的担神,里面只用getText函數(shù)沒有getName函數(shù),于是javascript就會尋找i的_proto_屬性始花,而i的proto屬性所指向的其實就是A.prototype妄讯,所以javascript就在A.prototype里面找getName函數(shù)孩锡,找到了就調(diào)用。所以第二段代碼中優(yōu)先調(diào)用返回Text的那個getName函數(shù)亥贸。

javascript里面還有一種對象就是對象字面量躬窜,對象字面量的是否擁有Function.prototype或者Object.prototype的函數(shù)呢
請看實驗

var a = {
    getName:function(){
        return "a";
    }
}
console.log(a.__proto__);//{}
console.log(a.prototype);//undefined

console.log(a.__proto__ === Object.prototype);//true

由于對象字面量不是由函數(shù)對象克隆的,所以沒有Function.prototype里面的方法炕置,因為a._proto_指向的是Object.prototype荣挨,這就說明javascript只能在a本身和Object.prototype里面找調(diào)用的函數(shù)。

總結

由上面以一些內(nèi)容我們可以得出:

1.javascript函數(shù)調(diào)用順序是查找對象的原型(即朴摊,對象的_proto_屬性)默垄,一層一層的往上找,直到遇到該函數(shù)或者undefined才停止甚纲。

2.函數(shù)作為特殊的對象口锭,它的原型是Function.prototype,能夠調(diào)用Function.prototype里面的方法介杆,而Function.prototype的原型又是Object.prototype鹃操,故而函數(shù)對象既能調(diào)用Function.prototype里面的方法,還能調(diào)用Object.prototype里面的方法春哨,這就說函數(shù)對象即是“函數(shù)”又是對象荆隘。

3.普通對象的原型是其構造函數(shù)的原型(即,A.prototype)赴背,而A.prototype的原型是Object.prototype椰拒,所以,普通對象只能調(diào)用它本身和Object.prototype內(nèi)的函數(shù)

4.對象字面量的原型是Object.prototype癞尚。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耸三,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子浇揩,更是在濱河造成了極大的恐慌仪壮,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胳徽,死亡現(xiàn)場離奇詭異积锅,居然都是意外死亡,警方通過查閱死者的電腦和手機养盗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門缚陷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人往核,你說我怎么就攤上這事箫爷。” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵虎锚,是天一觀的道長硫痰。 經(jīng)常有香客問我,道長窜护,這世上最難降的妖魔是什么效斑? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮柱徙,結果婚禮上缓屠,老公的妹妹穿的比我還像新娘。我一直安慰自己护侮,他們只是感情好敌完,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著概行,像睡著了一般蠢挡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凳忙,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天业踏,我揣著相機與錄音,去河邊找鬼涧卵。 笑死勤家,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的柳恐。 我是一名探鬼主播伐脖,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼乐设!你這毒婦竟也來了讼庇?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤近尚,失蹤者是張志新(化名)和其女友劉穎蠕啄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體戈锻,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡歼跟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了格遭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哈街。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拒迅,靈堂內(nèi)的尸體忽然破棺而出骚秦,到底是詐尸還是另有隱情她倘,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布作箍,位于F島的核電站帝牡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蒙揣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一开瞭、第九天 我趴在偏房一處隱蔽的房頂上張望懒震。 院中可真熱鬧,春花似錦嗤详、人聲如沸个扰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽递宅。三九已至,卻和暖如春苍狰,著一層夾襖步出監(jiān)牢的瞬間办龄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工淋昭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留俐填,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓翔忽,卻偏偏與公主長得像英融,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子歇式,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

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

  • 在JavaScript中驶悟,原型鏈作為一個基礎,老生長談材失,今天我們就來深入的解讀一下原型鏈痕鳍。 本章主要講的是下面幾點...
    Devinnn閱讀 1,405評論 1 6
  • 1,前言 下面是2008年Github創(chuàng)建以來豺憔,各種編程語言的排名情況 其中JavaScript自2015年之后就...
    拉丁吳閱讀 330評論 0 0
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持额获,譯者再次奉上一點點福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠恭应,并抽取幸運大...
    HetfieldJoe閱讀 3,002評論 4 14
  • 王大睿閱讀 122評論 0 0
  • 射日奔月新傳: 嫦娥后羿欲比聰抄邀, 二人抬頭望蒼穹, 后羿拈鬮先開始昼榛, 正逢驕陽逞熱兇境肾。 火燒大地屠萬物剔难, 后羿無奈...
    云之憾閱讀 123評論 0 0