原型鏈的查找原則和動態性
js原型大家都不陌生,但是涉及到原型鏈有些時候會蒙圈(我本人就是),下面介紹一下我對原型鏈的理解。
就近查找原則
對象訪問一個屬性,假如對象本身沒有這個屬性,會從原型鏈的底端向上查找這個屬性。
// 創建一個‘爺爺’
function Ground() {}
Ground.prototype = {
name: '趙' // 爺爺的姓趙
}
let ground = new Ground()
// 創建一個繼承‘爺爺’的‘爸爸’
function Father() {}
Father.prototype = ground // ‘爸爸’構造函數的原型指向實例‘爺爺’
let father = new Father()
console.log(father.name)
// '趙'
father.name = '李' // ‘爸爸’改姓‘李’
// 創建一個‘你’
function You() {}
You.prototype = father // ‘你’構造函數的原型指向實例‘爸爸’
let you = new You()
console.log(you.name)
// '李'
動態性
實例和原型通過_proto_連接(非標準,但絕大部分瀏覽器都支持),原型是一個對象,所以同樣放在堆中,_proto_是指向原型。
// 接着上面的代碼
father.name = '周'
console.log(child.name)
// 周
關於constructor
當創建一個函數時,函數自帶的prototype屬性,指向一個‘默認的對象’(原型),這個‘默認的對象’有兩個默認屬性constructor、proto,_proto_指向‘默認的對象’的原型,constructor指向構造函數。
function test() {}
console.log(test.prototype)
{
constructor: f test()
_proto_: Object
}
constructor只存在於函數的原型對象上