Javascript的原型、原型鏈、原型鏈繼承

原型

  在javascript中,原型分有兩種:顯示原型(prototype)和隱式原型(__proto__)。

__proto__(隱式原型)

    JavaScript中任意對象都有一個內置屬性`prototype`,在ES5之前沒有標準的方法訪問這個內置屬性,但是大多數瀏覽器都支持通過__proto__來訪問。ES5中有了對於這個內置屬性標準的Get方法Object.getPrototypeOf().

prototype(顯式原型)

  這是函數對象特有的屬性。這個屬性是一個指針,指向一個對象,這個對象的用途就是包含所有實例共享的屬性和方法(我們把這個對象叫做原型對象)。原型對象也有一個屬性,叫做constructor,這個屬性包含了一個指針,指回原構造函數。

例如:

var a = {};
console.log(a.__proto__);
// => Object {…}
console.log(a.prototype);
// => undefined
 
function b(){}
console.log(b.__proto__)
// => function () { [native code] }
console.log(b.prototype)
// => Object {…}

注:Object.prototype__proto__值爲null

區分__proto__prototype

定義

 這兩個名次的概念在上文中已經做了解釋,不贅述。

作用

prototype用來實現基於原型的繼承與屬性的共享。

__proto__構成原型鏈,同樣用於實現基於原型的繼承。

二者的關係

__proto__es5裏指向構造函數的prototype,在es6裏指向該構造函數。

小結

    1.任意對象(在javascript中,所有東西都是對象)都有屬性__proto__,指向該對象的構造函數的原型對象(prototype)。

    2. 函數對象除了有屬性__proto__,還有屬性prototypeprototype指向該方法的原型對象(prototype)。

原型鏈

javascript中,每個對象和原型對象(prototype)都有一個原型(__proto__),對象的原型指向構造函數(父)的原型對象(prototype),而原型對象(prototype)的原型(__proto__)指向父的父的原型對象(prototype),這樣便形成了通過原型層層連接起來的關係,我們把它稱爲原型鏈。聽起來很拗口,我簡單畫了個圖希望能幫助你理解:

wKioL1lZ9Dvi0vMwAAA7r6AnNsE162.png

由上圖可見,__proto__是實現原型鏈的關鍵,而prototype則是原型鏈的組成。另外,所有構造器/函數的__proto__都指向Function.prototype,它是一個空函數(Empty function)。

原型鏈繼承

在訪問一個對象的某個屬性時,首先在該對象的內部查找,若有則返回給屬性值,若沒找到,則從該對象的原型(__proto__)所指向的原型對象(構造器的prototype)中查找,若還是找不到,則繼續從該原型對象(prototype)的原型(__proto__)所指向的原型對象中查找,以此類推,知道找到爲止,若找不到則返回undefined

利用這一思想,我們直接將子類的原型對象指向父類的某個實例,則子類創建的所有實例都會繼承了父類的所有屬性,這就是原型鏈繼承。如:

function Parant (name, age) {
    this.name = name;
    this.age = age;
}
Parant.prototype.say = function(){
    console.log('hello, my name is ' + this.name);
};

function Child() {
}

Child.prototype = new Parant('pursue');

var man1 = new Child();
man1.say(); //hello, my name is pursue
var man2 = new Child();
console.log(man1.say === man2.say);//true
console.log(man1.name === man2.name);//true


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章