国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[學習筆記] 小角度看JS原型鏈

Cciradih / 1883人閱讀

摘要:雖然在腳本中沒有標準的方式訪問,但在每個對象上都支持一個屬性,用于訪問其構造函數的原型對象。說的是構造函數和原型對象之間的關系,說的是實例對象和原型對象之間的關系。

前言

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

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

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

乍一看真的有點懵,仔細研究了一下,發現還是對原型理解不透徹,所以總結一篇,填個洞~

Function和Object

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

原型

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

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

重要的事情再說一遍:
構造函數通過 prototype 屬性訪問原型對象。
實例對象通過 [[prototype]] 內部屬性訪問原型對象,瀏覽器實現了 _proto_ 屬性用于實例對象訪問原型對象。

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

再重復一遍。。prototype說的是構造函數和原型對象之間的關系,__proto__說的是實例對象和原型對象之間的關系。

原型鏈

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

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

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

Function 和 Object

FunctionObject 之間的關系有點繞:
Object 是構造函數,既然是函數,那么就是Function的實例對象;Function是構造函數,但Function.prototype是對象,既然是對象,那么就是Object的實例對象。

一切對象都是Object的實例,一切函數都是Function的實例。
ObjectFunction的實例,而Function.prototypeObject的實例。

二者的關系如下圖所示。

可見,Object作為構造函數,它有 prototype 屬性指向 Object.prototype , 作為實例對象, 它有 Object.__proto__ 指向Function.prototypeFunction是構造函數,它有prototype屬性指向Function.prototype,而Function是函數,從而也是Function的實例,所以它有Function.__proto__指向Function.prototype,從而 Function.__proto__ === Function.prototypetrue

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

原題解析

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

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

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

所以,原型鏈問題一應要畫圖啊~

原題擴展

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

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

讀到這里,有沒有發現函數一個比較特殊的地方?
一般的對象,只有一個__proto__屬性用于訪問其構造函數的原型對象,而對于函數來說,它既是函數又是對象。
作為函數,它生來就有prototype屬性指向其原型對象函數名.prototype
作為Function的實例對象,它有__proto__屬性指向Function.prototype
通常,這兩個屬性是指向兩個對象的,但Function的這兩個屬性指向相同,都指向Function.prototype

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

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

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

參考

js 原型的問題 Object 和 Function 到底是什么關系?—— 高票答案

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/85938.html

相關文章

  • JS筆記

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...

    rottengeek 評論0 收藏0
  • [學習筆記] JavaScript 閉包

    摘要:但是,必須強調,閉包是一個運行期概念。通過原型鏈可以實現繼承,而與閉包相關的就是作用域鏈。常理來說,一個函數執行完畢,其執行環境的作用域鏈會被銷毀。所以此時,的作用域鏈雖然銷毀了,但是其活動對象仍在內存中。 學習Javascript閉包(Closure)javascript的閉包JavaScript 閉包深入理解(closure)理解 Javascript 的閉包JavaScript ...

    sunsmell 評論0 收藏0
  • JS中的原型原型的認識

    摘要:在上面的各種原型的變換中,其實難點就在于構造函數也是對象原型對象等所有對象都由構造這四個點。 這篇文章主要是學習一下JavaScript中的難點------原型和原型鏈 自定義一個對象 我們學習一門編程語言,必然要使用它完成一些特定的功能,而面向對象的語言因為符合人類的認知規律,在這方面做得很好,今天我以JS為例,探索一下JS不同于其他面向對象的語言的地方-------原型和原型鏈 首...

    Juven 評論0 收藏0
  • JS中的原型原型的認識

    摘要:在上面的各種原型的變換中,其實難點就在于構造函數也是對象原型對象等所有對象都由構造這四個點。 這篇文章主要是學習一下JavaScript中的難點------原型和原型鏈 自定義一個對象 我們學習一門編程語言,必然要使用它完成一些特定的功能,而面向對象的語言因為符合人類的認知規律,在這方面做得很好,今天我以JS為例,探索一下JS不同于其他面向對象的語言的地方-------原型和原型鏈 首...

    Shimmer 評論0 收藏0

發表評論

0條評論

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