前言
這篇要介紹的是用 instanceof 這個函式,將會沿用上一篇的範例進行解說。
語法
instanceof 這個運算子用于檢測某個建構函式的 prototype 是否出現在某個實體物件的原型鏈上。
語法如下:
object instanceof constructor
從範例認識 instanceof
讀者可以先閱讀以下程式碼,這個範例跟上一篇比起來,差異在最后面增加了幾行的程式碼,其中使用到了 instanceof。
function Shape(x, y) { this.x = x; this.y = y;}Shape.prototype.move = function(x, y) { this.x += x; this.y += y;};function Rectangle(...args) { Shape.apply(this, args);}const properties = { name: { value: "長方形", enumerable: true, writable: true, }, getPos: { value: function () { console.log(`Current Position: ${this.x}, ${this.y}.`); }, },};Rectangle.prototype = Object.create(Shape.prototype, properties);Rectangle.prototype.constructor = Rectangle;const rect = new Rectangle(0, 0);console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // trueconsole.log('Is rect an instance of Shape?', rect instanceof Shape); // true
前面說到 instanceof 這個運算子用于檢測某個建構函式的 prototype 是否出現在某個實體物件的原型鏈上,所以觀察程式碼后,會發現 rect instanceof Rectangle
或是 rect instanceof Shape
都是 true。
對照圖來看,的確 Rectangle 和 Shape 的 prototype 都在原型鏈上。
使用 instanceof 判定型別
因為使用 typeof 去判斷物件型別時蠻多情況都會印出 object,所以改成用 instanceof,可以更加細分例如是陣列、物件、Date 物件...等。
console.log(typeof [1, 2, 3]); // 'object'console.log(typeof { name: 'harry' }); // 'object'console.log(typeof new Date); // 'object'console.log(typeof function() {}); // 'function'console.log([1, 2, 3] instanceof Array); // trueconsole.log({ name: 'harry' } instanceof Object); // trueconsole.log(new Date() instanceof Date); // trueconsole.log(new String() instanceof String); // trueconsole.log(function() {} instanceof Function); // true
實作 instanceof
最后,我們來嘗試著自己實作一個 instanceof。
實作的觀念就是根據原型鏈一直去找指定物件(第一個參數)的 __proto__
,如果有找到,就回傳 true,原型鏈都找完還是沒找到則回傳 false。
function myInstanceof(obj, target) { while (true) { if (obj === null) return false; if (obj === target.prototype) return true; obj = obj.__proto__; }}
我們可以將前面範例的 rect 物件和 Rectangle、Shape 函式拿來驗證:
console.log(myInstanceof(rect, Rectangle) );// true,因為 rect.__proto__ === Rectangle.prototypeconsole.log(myInstanceof(rect, Shape) );// true,因為 rect.__proto__.__proto__ === Rectangle.prototypeconsole.log(myInstanceof(rect, String) );// false,原型鏈找不到 String.prototype
原型繼承的系列文就到這邊結束了,明天將會進入重要的非同步處理的系列。
參考資料 & 推薦閱讀
MDN instanceof
自己實現一個instanceof