摘要:另外常說的的構造函數,就是指這個。按照理解,可能會這樣的疑問指向構造函數再次提醒,是一個對象的,所以這個對象的構造函數是它自己自己創建自己么額。。。
本文由用途意義,進行腦測解析,從需求角度走一遍原型鏈的發展。
js中沒有類(沒有類,沒有類,重要的事情說3遍)只有對象,怎么才能做到繼承的效果?
var a={x:1} var b={}; b.__proto__=a;
接下來進行約定,當訪問b.x但不存在時,就自動去訪問b.__proto__.x。
邏輯上就這么一回事。不過需要注意,這里說的只是訪問。b.x=2這種是無法對a,也就是b.__proto__造成影響的;同時這個為b賦予了x屬性,b.x將覆蓋掉b.__proto__.x。
通俗點總結,就是給對象掛一個父對象,當對象沒有相應屬性時,就去它父對象那里找。
var A=function(){ } var b = new A();
這個時候又該怎樣用__proto__實現繼承效果?
首先函數也是一個對象,除了A();這樣以函數調用,還能A.x=1;這樣把A當普通對象使用(下文中函數、函數對象,都是一回事)。知道這個后實現繼承很簡單,增加一個屬性即可:
A.prototype={constructor: A};//提醒一下怕忘記了,這里相當于A增加了屬性prototype A.prototype.x=1; b.__proto__ = A.prototype;
js會為每個這樣new出來的對象做這個處理,自己不用寫。
顯然,這里的A.prototype就類似與一開始例子中的a,往A.prototype增加屬性,那么所有new A()出來的對象都能訪問到這個新的屬性。
為什么js要默認增加constructor: A這個屬性到prototype中?這里與new操作符有關,是為了解決另一個問題。另外常說的prototype的構造函數,就是指這個。
總結:
反正就是通過new 函數()這樣出來的對象,其__proto__默認指向構造函數(這里說的是函數對象本身,它跟在new后面也被稱作構造函數)的prototype屬性。
實際上我覺得一般不以這個方法進行有大量屬性的繼承,一是查找有無屬性的效率問題,二是new時構造方法把this改為新建對象的指向就足以完成屬性的添加和賦值,無需操作prototype進行繼承。
__proto__、prototype是什么一回事相信已經了解,剩下的就是經常把人繞暈的Object.prototype、Function.prototype這些東西了。
先提一下,Object、Function都是一個函數對象,跟上面的A差不多,既能new Object()也能Object.xxx這樣用。
Object:1.所以var b=new Object();后,b.__proto__===Object.prototype這個應該沒有什么疑問。
2.新的標準中可用b=Object.creat(a),可當作是b=new Object(); b.__proto__=a,還是這套操作,問題不大。
3.如果是var b={}這種直接通過字面量創建對象,js會自動進行b.__proto__=Object.prototype,知道后問題也不大。
4.就是默認情況下,你不手動搞__proto__、prototype的指向,最終__proto__都會去指向Object.prototype。
5.Object.prototype
本質上跟前面示例中的prototype沒什么不同,只是這個prototype會被js自動增加一些屬性
6.Object.prototype.__proto__===null 跟在c++/java中遍歷鏈表一樣,當__proto__為null時說明到頭了。當作js自動設置上去的就行,沒什么其他特殊
7.Object.__proto__===Function.prototype 下面再講。
Function:1.所有的函數對象都是Function的實例。
不是說沒有類嗎,這個實例又是什么意思?
emmm,習慣說法而已,具體什么操作沒研究也不懂,或許當作js自動這樣做:
var f=function(){} f.__proto__=Function.prototype; //或者這樣理解 var f=new Function(); 然后把你的代碼放進去f
2.Function.__proto__===Function.prototype;
前面提過Object、Function都是一個函數對象,把它們代入第1點例子的f就行。上面第6點同理。
按照理解,可能會這樣的疑問:Function.__proto__指向構造函數(再次提醒,是一個對象)的prototype,所以Function這個對象的構造函數是它自己?自己創建自己么?
額。。。我覺得這種操作可能就是為了統一,只要記住“所有函數對象的__proto__都是Function.prototype”就行。
3.Function.prototype.__proto__===Object.prototype;
沒什么特別的,把Function.prototype代入上面Object第1點的b就行,不要特殊看待,硬要說與b不同的話,只是因為“函數對象的prototype默認會被增加一個constructor屬性”而已,沒什么大問題
1.我們在js中說的“類型”,可以說只是習慣用語,實際上仍舊是沒有所謂的類概念的,只有用對象來“模擬類”。
2.prototype就是指向一個普通對象prototype=new Object(),只不過這個對象被添加其他一些屬性后,再被自動放到到函數對象的屬性中。
3.__proto__就是 原型/原型對象,不斷的找原型的原型最終到--->Object.prototype--->Object.prototype.__proto__ (null)。原型對象可能是一個普通的對象;也可能是js自動放入到函數對象的prototype
4.我覺得js這套東西根本目的是批量為對象賦予屬性同時減少代碼冗余,上面解析的Object、Function、例子中的A都只是函數對象,不是像java一樣的類,平時說對象的類型只是方便日常交流,instanceof也只是很粗暴的遞歸比較對象__proto__ === 函數對象.prototype這種。把類的概念丟掉,保留對象、屬性這概念,從這出發又回頭去實現“類”、“繼承”這東西,就出來這么套東西。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98098.html
摘要:寫在前面如果說是一本武學典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術是從底層上去理解,那種工程師和碼農的區別就在于對底層的理解,當你寫完一行代碼,或者你遇見一個解決的速度取決于你對底層的理解。 寫在前面 如果說JavaScript是一本武學典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對九陽神功是這樣描述的:練成「九陽神功」后,會易筋洗髓;生出...
摘要:寫在前面如果說是一本武學典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術是從底層上去理解,那種工程師和碼農的區別就在于對底層的理解,當你寫完一行代碼,或者你遇見一個解決的速度取決于你對底層的理解。 寫在前面 如果說JavaScript是一本武學典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對九陽神功是這樣描述的:練成「九陽神功」后,會易筋洗髓;生出...
摘要:寫在前面如果說是一本武學典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術是從底層上去理解,那種工程師和碼農的區別就在于對底層的理解,當你寫完一行代碼,或者你遇見一個解決的速度取決于你對底層的理解。 寫在前面 如果說JavaScript是一本武學典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對九陽神功是這樣描述的:練成「九陽神功」后,會易筋洗髓;生出...
原型和原型鏈是js中的重點,明白了原型和原型鏈會讓我們在后面不管是學習還是工作都會更加高效,也是成為js大神的必經之路,并且原型和原型鏈會是面試中必不可少的話題。 之前面試時也碰到過很多關于原型和原型鏈的問題,對它了解,但沒有總結過,這些天看到一些文章有涉及到原型,就總結一下。 一,函數對象 所有引用類型(函數,數組,對象)都擁有__proto__屬性(隱式原型) 所有函數擁有prototype...
摘要:說白了,原型就是構造函數用來構造新實例的模板對象。什么是原型鏈先回答什么是原型。例如這個原型的原型就是這個構造函數的,既這個原型對象。這些原型對象通過像鏈子一樣連起來,就叫做原型鏈。 原型鏈初步學習 這篇博客只是我初步理解原型鏈的一個個人學習筆記,寫的比較粗略,且有的地方可能理解錯誤. 更多更專業的關于原型鏈的解釋請看JavaScript深入之從原型到原型鏈和阮一峰的博客:Javas...
閱讀 1849·2021-11-25 09:43
閱讀 1491·2021-09-02 15:21
閱讀 3453·2019-08-30 15:52
閱讀 1501·2019-08-30 12:48
閱讀 1295·2019-08-30 10:57
閱讀 2929·2019-08-26 17:41
閱讀 681·2019-08-26 11:59
閱讀 1366·2019-08-26 10:41