拾遺記2:js原型鏈

原型(對象屬性)

在JavaScript中,每個函數都有一個對象屬性(prototype),其指向另外一個對象。函數

爲什麼要設計prototype對象屬性?
JavaScript語言在設計時,其設計師不想將這門語言設計的過爲複雜,不想提升語言學習門檻,所以沒有引入類。可是其借鑑了new關鍵字,經過new關鍵字加構造函數的方式建立實例對象。若是隻有構造函數,那麼怎麼實現多個實例對象之間共享屬性和方法呢?爲了實現共享,設計師爲構造函數添加了prototype屬性,該屬性指向一個對象,全部實例之間共享的屬性和方法就放在這個對象上,不須要共享的屬性和方法就放在構造函數裏面,實例對象在建立完成以後,將自動引入prototype對象的屬性和方法。學習

function Person(name) {
    this.name = name
}
// 原型上添加一個共享方法
Person.prototype.say = function () {
    console.log(`my name is ${this.name}`)
}
let zs = new Person('zhangsan')
// 實例對象能夠訪問原型上的共享方法
zs.say()

原型鏈

在原型中咱們得知,全部的構造函數都有一個prototype屬性,由此構造函數建立的實例對象都能自動獲取prototype上面共享的屬性和方法。那麼實例對象是如何獲取的?實例對象都有實例對象和原型之間的一種連接,也就叫原型鏈。this

function Person(name) {
    this.name = name
}
Person.prototype.say = function () {
    console.log(`my name is ${this.name}`)
}
let zs = new Person('zhangsan')
// 實例對象proto屬性指向構造函數的原型
console.log(zs.__proto__ === Person.prototype) // true

因爲原型也是一個對象,能夠看做是Object的一個實例,所以,其__proto__屬性指向Object的原型。prototype

console.log(Person.prototype.__proto__ === Object.prototype) // true

因爲全部function都是由Fucntion生成的,也就是全部的函數能夠看做是Function的實例對象,所以函數的__proto__指向Function的原型。設計

console.log(Person.__proto__ === Function.prototype) // true

constructor

在每一個函數的原型prototype中都有constructor屬性,它保存了對函數的引用。code

console.log(Person.prototype.constructor === Person)

// 因爲constructor保存了一個引用,所以能夠用其實例化一個對象
let lisi = new Person.prototype.constructor('lisi')
lisi.say()
相關文章
相關標籤/搜索