摘要:說白了,原型就是構造函數用來構造新實例的模板對象。什么是原型鏈先回答什么是原型。例如這個原型的原型就是這個構造函數的,既這個原型對象。這些原型對象通過像鏈子一樣連起來,就叫做原型鏈。
原型鏈初步學習
這篇博客只是我初步理解原型鏈的一個個人學習筆記,寫的比較粗略,且有的地方可能理解錯誤.
更多更專業的關于原型鏈的解釋請看JavaScript深入之從原型到原型鏈和阮一峰的博客:Javascript繼承機制的設計思想
JS標準庫里幾個構造函數之間的關系
每個對象都有toString()和valueOf()函數,如果每個對象里都存這樣的相同的函數,那會浪費內存.
問題解決方法:原型鏈
把toString()和valueOf()等函數多帶帶存放在一個對象里,原來對象里的toString()和valueOf()只存地址,指向這個地址
當聲明對象是,出來自己定義的屬性,還有一個隱藏的屬性
__proto__ 里面存的是toString()和valueOf()等的地址
他的值就是公用屬性的值
共有的屬性和方法
在執行o1.toString()是發生的事:
首先看o1
是不是真正的對象,如果不是,就包裝成臨時對象,用完再回收垃圾,然后進入對象,看他有沒有toString方法,如果有特有的toString(),就用,如果沒有,就進入__proto__屬性去找toString()方法.
說明所有的toString()都是同一個地址
如果這個對象不是普通對象擁有特有的方法,會一層一層去找
代碼:
第一層的toString()是Number()特有的,可以轉換成16進制
toString(16),第二層里面的的toString()是所有對象都有的公共屬性.比如找valueOf()如果在第一層里 __proto__ 找不到,就去第二層找.
數字對象普通對象
結構:
原型鏈
所有的共有屬性,,如果沒有東西引用他,就會被垃圾回收,那么誰在引用他呢?
答案是 prototype ,prototype的意思是 原型.
所有函數都有protoype屬性,包括構造函數.即String(),Number(),Boolean(),Object()有protoype
在最開始JS初始化的時候,函數的protoype屬性會加載到內存當中
原型===共有屬性
Object.prototype意思還是Object的共有屬性
Object是構造函數(JS里函數也是一種對象,也可以有方法,可以 有屬性)
函數名字加()就是執行.
Number的共有屬性
共有屬性的共有屬性
其他String,Boolean的原型也是一樣
new做的事情,一創造一個哈希,二綁定原型(共有屬性),即把__proto__指向該有的共有屬性,也就是原型
__proto__與prototype的關系[__proto__指向prototype],
在無代碼情況下
window里面有Number屬性(函數也是對象,也可以有屬性)
實際上為
Number:function Number(){}這個
無代碼的時候,即為下面這樣,瀏覽器已經將其初始化好了.
可以看到prototype是用來指向這些共有屬性的,不然這些共有屬性就被垃圾回收了,所以要用一個線來牽引著.
如圖
寫了代碼之后
所以:
prototype是瀏覽器開始就準備好了的,用來防止共有屬性被垃圾回收的,
__proto__是在開始寫代碼的時候用來引用共有函數的.
String.prototype是String的公用屬性的引用,是JS在初始化的時候就已經存在的,用他是因為如果不用他,那么公用屬性就跑了,被垃圾回收了
"s".__proto__是String的公用屬性的引用,是在聲明新對象的時候存在的,有他是因為我要用他,用公用屬性
共同點就是都是公共屬性的引用.
var o1 = {}; o1.__proto__ === Object.prototype//true
Number.prototype.__proto__===Object.prototype//true
var s1 = new String("s1"); s1.__proto__ === String.prototype//true
String.prototype.__proto__ ===Object.prototype//true function DOG(name){ this.name = name; } DOG.prototype.__proto__ === Object.prototype//true對象與構造函數
形式
只有函數才能有prototype
兩個屬性對比:
共同點:存的地址相同,都指向同一個對象
不同點:一個是對象的屬性,一個是函數的屬性
面試題:
1
"1".__proto__
"1"會創建一個臨時String對象,然后指向String.prototype
2
函數.prototype 是一個對象,那么
var obj = 函數.prototype; obj.__proto__ === Object.prototype;//true 函數.prototype.__proto__ === Object.prototype;//true
成立(可以看上圖無代碼的時候)
Number.prototype.__proto__ === Object.prototype //true String.prototype.__proto__ === Object.prototype //true Boolean.prototype.__proto__ === Object.prototype //true
成立
原型鏈面試:怎么回答
JS 原型是什么?舉例
var a = [1,2,3]
只有0、1、2、length 4 個key
為什么可以 a.push(4) ,push 是哪來的?
a.__proto__ === Array.prototype(a是實例數組對象,Array是構造函數)
push函數 就是沿著 a.__proto__ 找到的,也就是 Array.prototype.push
Array.prototype 還有很多方法,如 join、pop、slice、splice、concat
Array.prototype 就是 a 的原型(proto)
聚完例子后用new對象舉例,說給面試官聽:
比若說
我們新創建一個構造函數
function Person() {}
然后根據構造函數構造一個新對象
var person1 = new Person();
每個函數都有一個 prototype 屬性,這個構造函數的 prototype 屬性指向了一個對象,這個對象正是調用該構造函數而創建的實例的原型。
當我們給Person的prototype的name屬性賦值為"Kevin"
Person.prototype.name = "Kevin"; var person1 = new Person(); var person2 = new Person(); console.log(person1.name) // Kevin console.log(person2.name) // Kevin
每一個新的實例對象對象都會從原型"繼承"屬性,實例對象擁有該原型的所有屬性。
說白了,原型就是 構造函數 用來 構造 新實例 的 模板對象。
這就是原型。
開始解釋原型鏈
那么我們該怎么表示實例與實例原型,也就是 person1 和 Person.prototype 之間的關系呢,這時候我們就要講到第二個屬性__proto__。
先回答什么是原型。在上面,然后繼續從__proto__開始往下說。
說:
JavaScript對象除了 null 都具有的一個屬性,叫__proto__,這個屬性會指向該對象的原型對象。
當讀取實例的屬性時,如果找不到,就會通過__proto__查找原型中的屬性,如果還查不到,就去找原型的原型。
例如Person.prototype這個原型的原型就是Object這個構造函數的prototype,既Object.prototype這個原型對象。然后,Person.prototype.__proto__就指向Object.prototype這個原型。然后Object.prototype原型是null。
這些原型對象通過__proto__像鏈子一樣連起來,就叫做原型鏈。
然后給面試官畫:
鏈子上都畫上__proto__
person1----->Person.prototype----->Object.prototype----->null
Array.prototype----->Object.prototype----->null
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/94834.html
摘要:原文鏈接關于的原型和原型鏈,看我就夠了一參考鏈接闖關記之原型及原型鏈之原型與原型鏈一篇文章帶你理解原型和原型鏈徹底理解原型鏈一的默認指向圖解和的三角關系原型和原型鏈三張圖搞懂的原型對象與原型鏈 溫故 創建對象的三種方式 通過對象直接量 通過new創建對象 通過Object.create() js中對象分為兩種 函數對象 普通對象 仔細觀察如下代碼 function Foo(na...
摘要:繼承可以使得子類具有父類別的各種屬性和方法。繼承是類與類之間的關系。繼承的實質就是兩次的原型搜索,像是實例屬性而不是繼承,才是繼承。更多用法見繼承。 前言 面試中最常會問到的問題:什么是繼承?如何分別用 ES5 和 ES6 實現?想要學習繼承,必須先學好原型與原型鏈,如果此部分還不清楚,請先學習此部分再來閱讀本文,可參考我的文章JS之原型與原型鏈或瀏覽其他相關的學習網站。 定義 繼承...
摘要:對應的關系圖如下講解了構造函數和原型對象之間的關系,那么實例對象和原型對象之間的關系又是怎么樣的呢下面講解。原型對象的指向的是構造函數和本身沒有屬性,但是其原型對象有該屬性,因此也能獲取到構造函數。 JavaScript進階 - 1. 原型和原型鏈的概念 我們好多經常會被問道JavaScript原型和原型鏈的概念,還有關于繼承,new操作符相關的概念。本文就專門整理了原型和原型鏈的概念...
摘要:的過程新生成了一個對象鏈接到原型綁定返回新對象在調用的過程中會發生以上四件事情,我們也可以試著來自己實現一個創建一個空的對象獲得構造函數鏈接到原型綁定,執行構造函數確保出來的是個對象對于實例對象來說,都是通過產生的,無論是還是。 showImg(https://segmentfault.com/img/bVbhZun?w=488&h=590); prototype 首先來介紹下 pro...
閱讀 2535·2023-04-25 14:54
閱讀 609·2021-11-24 09:39
閱讀 1818·2021-10-26 09:51
閱讀 3867·2021-08-21 14:10
閱讀 3493·2021-08-19 11:13
閱讀 2699·2019-08-30 14:23
閱讀 1816·2019-08-29 16:28
閱讀 3364·2019-08-23 13:45