javascript用法 - JavaScript中的instanceof運算符是什麼?




typescript instanceof (6)

的instanceof

左手側(LHS)操作數是正在測試右手側(RHS)操作數的實際對象,它是一個類的實際構造函數。 基本定義是:

Checks the current object and returns true if the object
is of the specified object type.

這裡有一些很好的例子 ,下面是一個直接來自Mozilla開發者網站的例子:

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)

值得一提的是,如果對象繼承自classe的原型,那麼instanceof評估為true:

var p = new Person("Jon");
p instanceof Person

因為pPerson.prototype繼承,所以pp instanceof Person

根據OP的要求

我已經添加了一些示例代碼和解釋。

當你聲明一個變量時,你給它一個特定的類型。

例如:

int i;
float f;
Customer c;

以上顯示了一些變量,即ifc 。 類型是integerfloat和用戶定義的Customer數據類型。 上述類型可以用於任何語言,而不僅僅是JavaScript。 但是,使用JavaScript聲明變量時,您並未明確定義類型,因此var x ,x可以是數字/字符串/用戶定義的數據類型。 那麼,什麼樣的instanceof會檢查對象,看看它是否是上面指定的類型,然後再採用我們可以執行的Customer對象:

var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!

上面我們已經看到c是用Customer類型聲明的。 我們已經新建了它並檢查它是否屬於Customer類型。 當然是,它回歸真實。 然後仍然使用Customer對象來檢查它是否是String 。 不,絕對不是一個String我們新建了一個Customer對象而不是一個String對象。 在這種情況下,它返回false。

這真的很簡單!

JavaScript中的instanceof關鍵字在第一次遇到時可能會相當混亂,因為人們傾向於認為JavaScript不是面向對象的編程語言。

  • 它是什麼?
  • 它解決了什麼問題?
  • 什麼時候適合,什麼時候不適合?

instanceof只是isPrototypeOf語法糖:

function Ctor() {}
var o = new Ctor();

o instanceof Ctor; // true
Ctor.prototype.isPrototypeOf(o); // true

o instanceof Ctor === Ctor.prototype.isPrototypeOf(o); // equivalent

instanceof僅僅依賴於對象構造函數的原型。

構造函數只是一個正常的函數。 嚴格來說,它是一個函數對象,因為所有東西都是Javascript中的一個對象。 而這個函數對像有一個原型,因為每個函數都有一個原型。

原型只是一個普通的對象,它位於另一個對象的原型鏈中。 這意味著在另一個對象的原型鏈中將對像作為原型:

function f() {} //  ordinary function
var o = {}, // ordinary object
 p;

f.prototype = o; // oops, o is a prototype now
p = new f(); // oops, f is a constructor now

o.isPrototypeOf(p); // true
p instanceof f; // true

應該避免使用instanceof操作符,因為它欺騙了JavaScript中不存在的類。 儘管class關鍵字不在ES2015中,因為class再次只是語法糖......但這是另一回事。


您可以使用它來進行錯誤處理和調試,如下所示:

try{
    somefunction();
} 
catch(error){
    if (error instanceof TypeError) {
        // Handle type Error
    } else if (error instanceof ReferenceError) {
        // Handle ReferenceError
    } else {
        // Handle all other error types
    }
}

我想,我剛剛找到了一個真實世界的應用程序,現在會更頻繁地使用它。

如果你使用jQuery事件,有時候你想寫一個更通用的函數,也可以直接調用(沒有事件)。 你可以使用instanceof來檢查函數的第一個參數是否是jQuery.Event一個實例,並做出適當的反應。

var myFunction = function (el) {                
    if (el instanceof $.Event) 
        // event specific code
    else
        // generic code
};

$('button').click(recalc);    // Will execute event specific code
recalc('myParameter');  // Will execute generic code

在我的情況下,函數需要為所有人(通過按鈕上的點擊事件)或只有一個特定的元素來計算東西。 我使用的代碼:

var recalc = function (el) { 
    el = (el == undefined || el instanceof $.Event) ? $('span.allItems') : $(el);
    // calculate...
};

這裡的其他答案是正確的,但他們沒有深入了解instanceof實際工作的方式,這可能會對某些語言律師感興趣。

JavaScript中的每個對像都有一個原型,可以通過__proto__屬性訪問。 函數也有一個prototype屬性,它是由它們創建的任何對象的初始__proto__ 。 當一個函數被創建時,它會被賦予一個獨特的prototype對象。 instanceof操作符使用這個唯一性給你一個答案。 如果您將它作為函數編寫,那麼以下是instanceof可能的樣子。

function instance_of(V, F) {
  var O = F.prototype;
  V = V.__proto__;
  while (true) {
    if (V === null)
      return false;
    if (O === V)
      return true;
    V = V.__proto__;
  }
}

這基本上解釋了ECMA-262第5.1版(也稱為ES5),第15.3.5.3節。

請注意,您可以將任何對象重新分配給函數的prototype屬性,並且可以在構造完成後重新分配對象的__proto__屬性。 這會給你一些有趣的結果:

function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();

f instanceof F;   // returns true
f instanceof G;   // returns true
g instanceof F;   // returns true
g instanceof G;   // returns true

F.prototype = {};
f instanceof F;   // returns false
g.__proto__ = {};
g instanceof G;   // returns false

關於“什麼時候適合,什麼時候不適合”的問題,我的2分錢:

instanceof在生產代碼中很少用到,但在你想要聲明你的代碼返回/創建正確類型的對象的測試中很有用。 通過明確您的代碼返回/創建的對像類型,您的測試將變得更加強大,作為理解和記錄代碼的工具。







instanceof