JS中的instanceof運算符


  js中的instanceof運算符

 MDN給出的解釋是:

  instanceof 運算符用於檢測構造函數的 prototype 屬性是否出現在某個實例對象的原型鏈上。

       看到這里我們就明白了instanceof是與原型和原型鏈有關系的,在弄懂instanceof之前我們就必須要了解什么是原型和原型鏈,關於原型和原型鏈詳細的解釋可以翻看我的另一篇博客徹底理解js的原型和原型鏈

 語法:

       object instanceof constructor 

    object         ——> 某個實例對象

    constructor ——>某個構造函數

   實例:

// 定義構造函數
function C(){}
function D(){}

//實例化對象 var o = new C(); o instanceof C; // true,因為 Object.getPrototypeOf(o) === C.prototype o instanceof D; // false,因為 D.prototype 不在 o 的原型鏈上 o instanceof Object; // true,因為 Object.prototype.isPrototypeOf(o) 返回 true C.prototype instanceof Object; // true,同上 C.prototype = {}; var o2 = new C(); o2 instanceof C; // true o instanceof C; // false,C.prototype 指向了一個空對象,這個空對象不在 o 的原型鏈上. D.prototype = new C(); // 繼承 var o3 = new D(); o3 instanceof D; // true o3 instanceof C; // true 因為 C.prototype 現在在 o3 的原型鏈上

  辨析instanceof和typeof:

  instanceof的功能類似於typeof,都是判斷類型。對於值的類型,如string/number/boolean我們都可以通過typeof判斷,但是typeof在判斷引用類型時,返回值只有object/function,你不知道它到底是一個object對象,還是數組,還是new Number等等。聽着還是有點模糊,那么我們通過一段代碼來更好的理解typeof的判斷類型是什么

   var a = 18;
    var b = 'smile';
    var c = true;
    var d = [];
    var e = {};
    function f() {

    }

    console.log(typeof (a));//number
    console.log(typeof (b));//string
    console.log(typeof (c));//boolean
    console.log(typeof (d));//object
    console.log(typeof (e));//object
    console.log(typeof (f));//function

 

  那么instanceof又是怎么判斷的呢?

  我們先假設有一個函數A,A有一個實例化對象a,instanceof的判斷規則是沿着a的__proto__這條線去找,同時沿着A的prototype這條線去找,如果兩條線能找到同一個引用,即同一個對象,就返回true,如果找到終點還沒有重合就返回false.同樣,我們也將通過一段代碼來理解instance的判斷類型

   function A() {

    }
    var a = new A();
    var b = [];

    console.log(a instanceof A);//true
    console.log(A instanceof Function);//true
    console.log(b instanceof Array);//true
    console.log(a instanceof Array);//false

 

  擴展   

  其實對於類型的判斷我們還可以使用constructor,至於constructor的原理在這里就不過多解釋了,想了解的可以翻看我的另一篇博客JS的原型和原型鏈

    var a = 4;
    var arr = [];
    var obj = {};
    function fun(){};
    console.log(a.constructor === Number);//true
    console.log(arr.constructor === Array);//true
    console.log(obj.constructor === Object);//true
    console.log(fun.constructor === Function);//true

  雖然constructor既可以判斷基本數據類型又可以判斷引用類型,但是它還是存在很多弊端的。

  比如它會出現跨框架問題(instanceof也存在),理想情況(單框架)下, var arr = new Array(), arr 自然是Array的實例,檢測結果當然准確。但具體應用中,如果使用多個框架(使用frame),瀏覽器中就會存在多個 window(Global)對象,每個 window 又都有自己的 Array 等一套構造函數,它們一一對應,卻並不相等。解釋起來很拗口,其實道理很簡單:在中國你說家在首都,誰都知道指的是北京。在美國如果你也說家在首都,別人又會理所當然地覺得你在講華盛頓。每個國家(框架、執行環境)都有自己的“首都(原型對象)”,但這個“首都”卻指向不同的位置(對象)。“首都”因所屬國家的不同而不同,Array因所屬的window不同而不同。所以使用 instanceof 的時候要確保“同一框架”這個前提條件。此外constructor還可能因為實現對象繼承時的疏忽導致錯誤結果,因為我們自己手動改變了默認的原型對象。

 


免責聲明!

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



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