JavaScript中instanceof的判斷依據


讀jquery源碼的時候,發現作者為了讓創建jquery對象更容易使用了用函數返回對象的方法

jQuery = function( selector, context ) {
    return new jQuery.fn.init( selector, context, rootjQuery );
}

jQuery 對象的方法都定義在jQuery.prototype 上,然后init也是原型上的一個方法,為了讓jQuery.fn.init構造函數能夠繼承jQuery.prototype上的方法把jQuery.fn.init.prototype指向了jQuery.prototype

jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    ...,
    init: function( selector, context, rootjQuery ) {},
    ...,
}
jQuery.fn.init.prototype = jQuery.fn;

這樣是妥善解決了方法繼承問題,但是有個疑問:構造函數jQuery.fn.init創建的實例的對象類型是jQuery對象嗎?

var obj = jQuery();
obj instanceof jQuery.fn.init //true
obj instanceof jQuery //這里obj好像跟jQuery 毫無關系

但是試了一下jQuery 方法創建的對象確實是jQuery的實例也就是說obj instanceof jQuery 為true;
於是就引出了JavaScript中instanceof的判斷依據是什么的困惑,百思不得其解,網上查了一下原來是根據實例的__proto__ 屬性。
instanceof的判斷依據:
在實現js的繼承的時候,每一個用new 構造出來的對象都會有一個私有的屬性,在firefox和chrome中這個私有的屬性叫做 __proto__,在 IE中也有一個這樣類的的私有屬性,只不過沒有暴露給用戶。
這個屬性指向其構造函數的 prototype ,在執行 o2 = new O2() 的時候會有類似這樣的賦值o2.__proto__ = O2.prototype所以在chrome 和 firefox中:
o2 instaneof O2 其實相當於 o2.__proto__ === O2.prototype || o2.__proto__.__proto__ === O2.prototype || ...
IE中也是類似,只不過這個屬性不叫 __proto__
P.S 繼承的實現:
當你讀取 o2.pro 的時候,會現在o2中尋找有沒有一個叫 pro 的屬性,沒有的話就去o2.__proto__中找有沒有,還沒有的話,就去o2.__proto__.__proto__中去找(記住一個對象的__proto__就是其構造函數的prototype)。。。這樣一直下去其實最終會找到 Object.prototype,這樣就實現了所有的對象都繼承了Object。
當你寫入 o2.pro 的時候就只會在o2中查找,不會遞歸的查找o2.__proto__,這樣就會得到一個新的(如果沒有的話)pro屬性,然后當你再次訪問 o2.pro 的時候,就是訪問的這個新的屬性,即使o2.__proto__中有這個屬性,這就完成了屬性/函數的重載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM