JS原形鏈

圖一: app

js prototype chain

圖二 函數

先上兩張關於原型鏈的圖,能夠從中發現四個部分instance(實例對象)自定義函數FunctionObjectspa

從一層f1.__proto__ === Foo.prototype提及

function Foo() {}
let f1 = new Foo()
// f1.__proto__引用了Foo.prototype
console.log(f1.__proto__ === Foo.prototype) // true
複製代碼

任何一個由new關鍵字生成的實例對象都會有一個__proto__引用函數的prototype。如上f1.__proto__ === Foo.prototype。那麼問題來了,實例對象的__proto__是如何引用函數的prototype對象的。prototype

  1. 重寫new關鍵字3d

    function new(Func, arguments) {
         let o = {}
         if (Func && typeof Func === 'function') {
             o.__proto__ = Func.prototype
             Func.apply(o, arguments)
             return o
         }
     }
    複製代碼

從重寫的new方法中,能夠知道,o.__proto__ = Func.prototype,實例對象的__proto__引用函數的prototype。是因爲關鍵字new方法實現的。code

解開了第一層的面紗,來看看第二層面紗cdn

函數對頂層函數的引用

從幾個問題談起對象

  1. Foo.__proto__ === Function.prototype // true
  2. Function.__proto__ === Function.prototype // true
  3. Object.__proto__ === Function.prototype // true

從圖一/二中均可以看出,任何一個函數自身也擁有一個__proto__,並引用頂層函數的prototype。可能這裏會有些奇怪,換一種思路,能夠理解爲任何函數都是頂層函數Function的對象,包括Function()和Object()函數blog

原形對象對原形對象的引用

  1. f1.__proto__ === Foo.prototype
  2. Foo.prototype.__proto__ === Object.prototype
  3. Function.prototype.__proto__ === Object.prototype
  4. Object.prototype.__proto__ null

沿着對象的原形,會逐級的往上,一直找到Object.prototype.__proto__ = null中止,對象原形的鏈的查找遵循f1.__proto__.__proto__....,這樣構成了JS的原形鏈。原型鏈

這裏須要注意的Object.prototype中定義了過個默認的方法,而且是不能修改的。

hasOwnProperty的使用

該方法不會去檢查對象的原形上是否存在指定的屬性,只會檢驗自己函數自己是否擁有這個屬性。

instanceof操做符的使用

a instanceof A
複製代碼

方法判斷的是對象是不是一個函數的實例,這裏的入參a必須是是一個實例對象,A是一個函數。該操做符會檢查a是否在A的原形鏈中,因此會出現一下狀況

Function instanceof Function // true
Object instanceof Fucntion // true
Obejct instanceof Object // true
Function instanceof Object // true
複製代碼
相關文章
相關標籤/搜索