亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JS原型鏈 詳解及示例代碼

 更新時間:2016年09月06日 09:11:33   投稿:lqh  
本文主要介紹JS原型鏈的知識,這里整理了相關(guān)資料及簡單實現(xiàn)示例代碼,有興趣的小伙伴可以參考下

前言

在 segmentfault 上看到這樣一道題目:

var F = function(){};
Object.prototype.a = function(){};
Function.prototype.b = function(){};
var f = new F();

問:f 能取到a,b嗎?原理是什么?

乍一看真的有點懵,仔細(xì)研究了一下,發(fā)現(xiàn)還是對原型理解不透徹,所以總結(jié)一篇,填個洞~

Function和Object

在解題之前,先再說說 原型、原型鏈,以及 Function 和 Object 的關(guān)系,這也是本文的重點。

原型

在創(chuàng)建一個函數(shù)的時候,會自動為其創(chuàng)建一個原型對象,可以通過函數(shù)的prototype屬性訪問到。

創(chuàng)建一個構(gòu)造函數(shù)的實例對象,該實例對象內(nèi)部將包含一個指針(內(nèi)部屬性),指向構(gòu)造函數(shù)的原型對象。ECMA-262 第5版中管這個指針叫[[prototype]]。雖然在腳本中沒有標(biāo)準(zhǔn)的方式訪問[[prototype]],但Firefox、 Safari、 Chrome在每個對象上都支持一個屬性 __proto__,用于訪問其構(gòu)造函數(shù)的原型對象。

重要的事情再說一遍:
構(gòu)造函數(shù)通過 prototype 屬性訪問原型對象。
實例對象通過 [[prototype]] 內(nèi)部屬性訪問原型對象,瀏覽器實現(xiàn)了 _proto_ 屬性用于實例對象訪問原型對象。

var F = function () {};
var f = new F();
// 假設(shè)F的原型對象是 p, 則
// F.prototype === p;
// f.__proto__ === p;

再重復(fù)一遍。。prototype說的是構(gòu)造函數(shù)和原型對象之間的關(guān)系,__proto__說的是實例對象和原型對象之間的關(guān)系。

原型鏈

類 A繼承B,B繼承C……其實就是A的原型對象中有指針指向B的原型對象,而B的原型對象中有指針指向C的原型對象……注意是原型對象之間的聯(lián)系,A B C 這三個構(gòu)造函數(shù)之間并沒什么關(guān)系,所以才稱為“原型鏈”吧~

假設(shè)a是A的實例對象,則 a 的原型鏈為下圖中紫色線條所示,橙色線條連接了構(gòu)造函數(shù)和其原型對象。

由圖可以看出,原型鏈的末端是Object.prototype.__proto__即null。當(dāng)查找a的某個屬性或方法時,首先查找a自身有沒有,沒有則沿著原型鏈一直查找,直到找到或者最后到null返回undefined。

Function 和 Object

Function 和 Object 之間的關(guān)系有點繞:

Object 是構(gòu)造函數(shù),既然是函數(shù),那么就是Function的實例對象;Function是構(gòu)造函數(shù),但Function.prototype是對象,既然是對象,那么就是Object的實例對象。

一切對象都是Object的實例,一切函數(shù)都是Function的實例。

Object是Function的實例,而Function.prototype是Object的實例。

二者的關(guān)系如下圖所示。

可見,Object作為構(gòu)造函數(shù),它有 prototype 屬性指向 Object.prototype , 作為實例對象, 它有 Object.__proto__ 指向Function.prototype。Function是構(gòu)造函數(shù),它有prototype屬性指向Function.prototype,而Function是函數(shù),從而也是Function的實例,所以它有Function.__proto__指向Function.prototype,從而 Function.__proto__ === Function.prototype 為 true。

可在Chrome控制臺下進行驗證,如圖。


原題解析

解決原型鏈問題最好的辦法就是畫圖了,經(jīng)過前面的分析,這個圖畫起來應(yīng)該不成問題,如下~

f 的原型鏈為藍(lán)色線所畫,所以 f 可以訪問到 a , 不能訪問到 b 。

如果不畫圖,乍一看,可能會覺得f 可以訪問到 b,那是可能跟我一樣誤認(rèn)為F.prototype指向Function.prototype,但其實F.prototype是對象而不是函數(shù),所以它的原型對象不會是 Function.prototype。

所以,原型鏈問題一應(yīng)要畫圖啊~

原題擴展

在上題中,f 只能訪問 a,不能訪問 b 。但 F 既可以訪問 a ,又可以訪問 b。如果把題修改成下面的樣子, F.b()的結(jié)果是什么呢?為什么呢?可以想一下哦~

var F = function(){};
Object.prototype.a = function(){};
Function.prototype.b = function(){ console.log('F.__proto__') };
F.prototype.b = function (){console.log('F.prototype');};

總結(jié)

讀到這里,有沒有發(fā)現(xiàn)函數(shù)一個比較特殊的地方?

一般的對象,只有一個__proto__屬性用于訪問其構(gòu)造函數(shù)的原型對象,而對于函數(shù)來說,它既是函數(shù)又是對象。

作為函數(shù),它生來就有prototype屬性指向其原型對象函數(shù)名.prototype。

作為Function的實例對象,它有__proto__屬性指向Function.prototype

通常,這兩個屬性是指向兩個對象的,但Function的這兩個屬性指向相同,都指向Function.prototype。

對于函數(shù) A( ) 來說,A.prototype 中的方法是供其實例對象調(diào)用的,自己并不會用;當(dāng)A 作為實例運行時,調(diào)用的是A.__proto__ 中的方法。也就是說,作為構(gòu)造函數(shù)使用時,走的是A.prototype這條鏈,方法、屬性賦給其實例;作為對象使用時,走的是A.__proto__這條鏈。在不同的場景下,分清它的身份就不會錯了。

整篇下來,感覺自己說的也比較絮叨……不足之處,還請各位指正~ 至于題目,真的不知道該叫什么好。。

愿本文能帶給堅持看完的你一些收獲~ ^_^

謝謝大家對本站的支持,后續(xù)繼續(xù)更新相關(guān)資料,幫助大家學(xué)習(xí)了解這部分知識!

相關(guān)文章

最新評論