目錄
- 前言
- 一、建構式
- 二、原型
- 三、原型鏈
- 1.__proto__和constructor
- 2.何為原型鏈
前言
與大部分面向物件語言不同,ES6之前并沒有引入類(class)的概念,JavaScript并非通過類而是直接通過建構式來創建實體,在介紹原型和原型鏈之前,我們有必要先復習一下建構式的知識,
一、建構式
建構式模式的目的就是為了創建一個自定義類,并且創建這個類的實體,建構式模式中擁有了類和實體的概念,并且實體和實體之間是相互獨立的,即實體識別,
建構式就是一個普通的函式,創建方式和普通函式沒有區別,不同的是建構式習慣上首字母大寫,另外就是呼叫方式的不同,普通函式是直接呼叫,而建構式需要使用new關鍵字來呼叫,
function Person(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
this.sayName = function () {
alert(this.name);
}
}
var per = new Person("孫悟空", 18, "男");
function Dog(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
var dog = new Dog("旺財", 4, "雄")
console.log(per);//當我們直接在頁面中列印一個物件時,事件上是輸出的物件的toString()方法的回傳值
console.log(dog);

每創建一個Person建構式,在Person建構式中,為每一個物件都添加了一個sayName方法,也就是說建構式每執行一次就會創建一個新的sayName方法,這樣就導致了建構式執行一次就會創建一個新的方法,執行10000次就會創建10000個新的方法,而10000個方法都是一摸一樣的,為什么不把這個方法單獨放到一個地方,并讓所有的實體都可以訪問到呢?這就需要原型(prototype)
二、原型
在JavaScript中,每當定義一個函式資料型別(普通函式、類)時候,都會天生自帶一個prototype屬性,這個屬性指向函式的原型物件,并且這個屬性是一個物件資料型別的值,
讓我們用一張圖表示建構式和實體原型之間的關系:

原型物件就相當于一個公共的區域,所有同一個類的實體都可以訪問到這個原型物件,我們可以將物件中共有的內容,統一設定到原型物件中,
三、原型鏈
1.__proto__和constructor
每一個物件資料型別(普通的物件、實體、prototype......)也天生自帶一個屬性__proto__,屬性值是當前實體所屬類的原型(prototype),原型物件中有一個屬性constructor, 它指向函式物件,
function Person() {}
var person = new Person()
console.log(person.__proto__ === Person.prototype)//true
console.log(Person.prototype.constructor===Person)//true
//順便學習一個ES5的方法,可以獲得物件的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

2.何為原型鏈
在JavaScript中萬物都是物件,物件和物件之間也有關系,并不是孤立存在的,物件之間的繼承關系,在JavaScript中是通過prototype物件指向父類物件,直到指向Object物件為止,這樣就形成了一個原型指向的鏈條,專業術語稱之為原型鏈,
舉例說明:person → Person → Object ,普通人繼承人類,人類繼承物件類
當我們訪問物件的一個屬性或方法時,它會先在物件自身中尋找,如果有則直接使用,如果沒有則會去原型物件中尋找,如果找到則直接使用,如果沒有則去原型的原型中尋找,直到找到Object物件的原型,Object物件的原型沒有原型,如果在Object原型中依然沒有找到,則回傳undefined,
我們可以使用物件的hasOwnProperty()來檢查物件自身中是否含有該屬性;使用in檢查物件中是否含有某個屬性時,如果物件中沒有但是原型中有,也會回傳true
function Person() {}
Person.prototype.a = 123;
Person.prototype.sayHello = function () {
alert("hello");
};
var person = new Person()
console.log(person.a)//123
console.log(person.hasOwnProperty('a'));//false
console.log('a'in person)//true
person實體中沒有a這個屬性,從 person 物件中找不到 a 屬性就會從 person 的原型也就是 person.__proto__ ,也就是 Person.prototype中查找,很幸運地得到a的值為123,那假如 person.__proto__中也沒有該屬性,又該如何查找?
當讀取實體的屬性時,如果找不到,就會查找與物件關聯的原型中的屬性,如果還查不到,就去找原型的原型,一直找到最頂層Object為止,Object是JS中所有物件資料型別的基類(最頂層的類)在Object.prototype上沒有__proto__這個屬性,
console.log(Object.prototype.__proto__ === null) // true

作者:浪里行舟
鏈接:原型與原型鏈詳解
來源:github
著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請注明出處,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/249402.html
標籤:JavaScript
