JS原型鏈、prototype、__proto__、原型鏈繼承詳解

prototype__proto__的區別:

Javascript中全部的對象都是Object的實例,並繼承Object.prototype的屬性和方法,也就是說,Object.prototype是全部對象的父級。javascript

在對象建立時,就會有一些預約義的屬性,其中定義函數的時候,這個預約義屬性就是prototype,這個prototype是一個普通的對象。 而定義普通的對象的時候,就會生成一個__proto__,這個__proto__指向的是這個對象的構造函數的prototype.java

function A () {}

let a = new A()
複製代碼

當咱們聲明一個函數A時就自動建立了prototype對象。而a是構造函數A的實例,這時候a是一個實例對象,由於實例對象只有__proto__屬性, 因此a只有__proto__屬性,此屬性指向A.prototypebash

因此:函數

// 每一個實例對象(object)都有一個私有屬性(稱之爲__proto__)指向它的原型對象(prototype)
a.__proto__ === A.prototype // true 
複製代碼

這就是prototype__proto__的區別。ui

原型鏈

咱們都知道對象都有一個toString方法。上述的實例化對象a也能夠toString。而實例化對象a自己並無toString的方法,那他就會沿着它的__proto__向他的構造函數A的prototype對象去找,而這裏也沒有,那他就會繼續沿着A.prototype.__proto__向上找。而A.prototype.__proto__指向的就是Object.prototype。(這也同時也解釋了爲何全部的javascript對象都具備Object的基本方法。)this

a.toString() === Object.prototype.toString() // true
複製代碼

這一層一層的連接關係就是原型鏈,層層向上直到一個對象的原型對象爲 null(Object.prototype.__proto__ === null)。根據定義,null 沒有原型,並做爲這個原型鏈中的最後一個環節。spa

用代碼表示就是:.net

a.__proto__ === A.prototype // true 
A.prototype.__proto__ === Object.prototype // true

==>
a.__proto__.__proto__ === Object.prototype // true
複製代碼

原型鏈繼承

有了上面的理論支持,再理解原型鏈繼承就十分簡單了prototype

function Parent(){
    this.name = 'mike';
}

function Child(){
    this.age = 12;
}
Child.prototype = new Parent(); // Child繼承Parent,經過原型,造成鏈條
複製代碼

這個時候Child.prototype已是{ name: 'mike' }code

let childA = new Child() // 建立實例

console.log(childA) // { age: 12 }
複製代碼

childA中並無name屬性,可是根據咱們在上面討論的,原型鏈會一層層向上找,因此:

childA.name === childA.__proto__.name === Child.prototype.name // true

console.log(childA.name) // mike
複製代碼

參考連接:

一、繼承與原型鏈

二、完全理解什麼是原型鏈,prototype和__proto__的區別。

相關文章
相關標籤/搜索