Java instanceof
instanceof 嚴格來說是Java中的一個雙目運算符,用來測試一個對象是否為一個類的執行個體
boolean result = obj instanceof Class
其中 obj 為一個對象,Class 表示一個類或者一個接口,當 obj 為 Class 的對象,或者是其直接或間接子類,或者是其接口的實作類,結果result 都傳回 true,否則傳回false。
總結就是:
- 隻要判斷對象obj 在 屬于Class的繼承鍊上,就傳回true
- obj必須為對象,是以 obj 必須為引用類型,不能是基本類型
- 基本資料類型:byte short int long float double char boolean
-
特殊類型:null
該類型沒有名字,是以不可能聲明為 null 類型的變量或者轉換為 null 類型,null 引用是 null 類型表達式唯一可能的值,null 引用也可以轉換為任意引用類型
- 如果 obj 為 null,那麼将傳回 false。
編譯器會檢查 obj 是否能轉換成右邊的class類型,如果不能轉換則直接報錯,如果不能确定類型,則通過編譯,具體看運作時定。
java資料類型看參看《再談Java資料結構—分析底層實作與應用注意事項》
JavaScript資料結構參看《再談js對象資料結構底層實作原理-object array map set》
對于前端,這裡隻是一個引子
JavaScript instanceof
The instanceof operator tests whether the prototype property of a constructor appears anywhere in the prototype chain of an object.
instanceof 運算符用來檢測 constructor.prototype 是否存在于參數 object 的原型鍊上。
instanceof操作符的内部實作機制和隐式原型、顯式原型有直接的關系。instanceof的左值一般是一個對象,右值一般是一個構造函數,用來判斷左值是否是右值的執行個體。它的實作原理是沿着左值的__proto__一直尋找到原型鍊的末端,直到其等于右值的prototype為止。
instanceof 的作用是判斷一個對象是不是一個函數的執行個體。比如 obj instanceof fn, 實際上是判斷fn的prototype是不是在obj的原型鍊上。是以
instanceof運算符的實質:用來檢測 constructor.prototype是否存在于參數 object的原型鍊上。
原生JS實作instanceof功能
核心就是左邊對象的__proto__的指向是否等于右邊的prototype屬性
function instanceofMethod (left, right) {
let prototype = right.prototype;
let proto = left.__proto__;
while (true) {
if (proto === prototype) return true;
if (proto === null) return false;
//若本次查找無結果,則沿着原型鍊向上查找
proto = proto.__proto__;
}
}
在《再談javascriptjs原型與原型鍊及繼承相關問題》

根據上圖展示的Object和Function的繼承依賴關系,我們可以通過instanceof操作符來看一下Object和Function的關系:
console.log(Object instanceof Object); // true
console.log(Object instanceof Function); // true
console.log(Function instanceof Object); // true
console.log(Function instanceof Function); // true
函數與對象互相依存,分别定義了事物的描述方法和事物的生成方法,在生成JS萬物的過程中缺一不可。
Function instanceof Function // true, why? Function.prototype是原型對象,卻是函數對象
- Object特殊在Object.prototype是憑空出來的。文法上,所有的{}都會被解釋為new Object();
- Function特殊在__proto__ == prototype。文法上,所有的函數聲明都會被解釋為new Function()。
我們來看Function和Object的特殊之處:
- Object是由Function建立的:因為Object.__proto__ === Funciton.prototype;
- 同理,Function.prototype是由Object.prototype建立的;
- Funciton是由Function自己建立的!
- Object.prototype是憑空出來的!
null instanceof null
基本包裝類型對象:ECMAScript還提供了3個特殊的引用類型: Boolean、Number、String。這些類型與其他内置對象類型相似,但同時具有各自的基本類型相應的特殊行為。實際上,每當讀取一個基本類型值得時候,背景就會建立一個對應的基本包裝類型的對象,進而讓我們能夠調用一些方法來操作這些資料。 包裝類型,是一個專門封裝原始類型的值,并提供對原始類型的值執行操作的API對象
其他内置對象與基本包裝類型對象的差別?
普通的内置對象與基本包裝類型的主要差別就是對象的生命期,使用new操作符建立的引用類型的執行個體,在執行流離開目前作用域之前都一直儲存在記憶體中,而自動建立的基本包裝類型的對象,則隻是存在于一行代碼的執行瞬間,然後立即被立即銷毀。這意味着我們不能再運作時為基本包裝類型值添加屬性和方法,也沒有所謂的 constructor了。
是以
console.log('a' instanceof String)//false
console.log(0 instanceof Number)//false
console.log(false instanceof Boolean)//false
null為一切對象的始祖
console.log(null instanceof null)
^
TypeError: Right-hand side of 'instanceof' is not an object