1. 程式人生 > 實用技巧 >原型與原型鏈

原型與原型鏈

  • 顯式原型與隱式原型
    • 每個函式都有一個 prototype 屬性, 稱為顯式原型屬性,預設指向一個 Object空物件, 即原型物件
    • 原型物件中有一個屬性 constructor, 它指向函式物件
    • 所有例項物件都有一個特別的屬性,__proto__,稱為隱式原型屬性
  • 顯式原型與隱式原型的關係
    • 函式的prototype: 定義函式時被自動賦值, 值預設為{}, 即用為原型物件
    • 例項物件的__proto__: 在建立例項物件時被自動新增, 並賦值為建構函式的prototype值
    • 原型物件即為當前例項物件的父物件
    • 給原型物件新增屬性(一般是方法), 例項物件可以訪問
  • 原型鏈
    • 所有的例項物件都有__proto__屬性, 它指向的就是原型物件
    • 這樣通過__proto__屬性就形成了一個鏈的結構---->原型鏈
    • 當查詢物件內部的屬性/方法時, js引擎自動沿著這個原型鏈查詢,如果最終沒找到, 返回undefined
    • 當給物件屬性賦值時不會使用原型鏈, 而只是在當前物件中進行操作
  • 注意
    • 函式的顯示原型指向的物件預設是空Object例項物件(但Object不滿足)
    • 所有函式都是Function的例項(包含Function) ,Function是通過new自己產生的例項
      Function = new Function()
    • Object的原型物件是原型鏈盡頭
      Object.prototype.__proto__ === null
  • 探索 instanceof
    • 表示式: A instanceof B
    • 如果B函式的顯式原型物件在A物件的原型鏈上, 返回true, 否則返回false
      console.log(Object instanceof Function) // true
      console.log(Object instanceof Object) // true
      console.log(Function instanceof Function) // true
      console.log(Function instanceof Object) // true
      

  • 測試題1.
    function A () {
    }
    A.prototype.n = 1
    var b = new A()
    A.prototype = {
      n: 2,
      m: 3
    }
    var c = new A()
    console.log(b.n, b.m, c.n, c.m)
    
  • 測試題2.
     function F (){}
     Object.prototype.a = function(){
       console.log('a()')
     }
     Function.prototype.b = function(){
       console.log('b()')
     }
     var f = new F()
     f.a()
     // f.b()
     F.a()
     F.b()
     console.log(f)
     console.log(Object.prototype)
     console.log(Function.prototype)