實(shí)例講解JavaScript中instanceof運(yùn)算符的用法
instanceof 運(yùn)算符簡介
在 JavaScript 中,判斷一個(gè)變量的類型嘗嘗會(huì)用 typeof 運(yùn)算符,在使用 typeof 運(yùn)算符時(shí)采用引用類型存儲(chǔ)值會(huì)出現(xiàn)一個(gè)問題,無論引用的是什么類型的對象,它都返回 “object”。ECMAScript 引入了另一個(gè) Java 運(yùn)算符 instanceof 來解決這個(gè)問題。instanceof 運(yùn)算符與 typeof 運(yùn)算符相似,用于識別正在處理的對象的類型。與 typeof 方法不同的是,instanceof 方法要求開發(fā)者明確地確認(rèn)對象為某特定類型。例如:
清單 1. instanceof 示例
var oStringObject = new String("hello world");
console.log(oStringObject instanceof String); // 輸出 "true"
這段代碼問的是“變量 oStringObject 是否為 String 對象的實(shí)例?”oStringObject 的確是 String 對象的實(shí)例,因此結(jié)果是”true”。盡管不像 typeof 方法那樣靈活,但是在 typeof 方法返回 “object” 的情況下,instanceof 方法還是很有用的。
instanceof 運(yùn)算符的常規(guī)用法:
通常來講,使用 instanceof 就是判斷一個(gè)實(shí)例是否屬于某種類型。例如:
清單 2. instanceof 常規(guī)用法
// 判斷 foo 是否是 Foo 類的實(shí)例
function Foo(){}
var foo = new Foo();
console.log(foo instanceof Foo)//true
另外,更重的一點(diǎn)是 instanceof 可以在繼承關(guān)系中用來判斷一個(gè)實(shí)例是否屬于它的父類型。例如:
清單 3. instanceof 在繼承中關(guān)系中的用法
// 判斷 foo 是否是 Foo 類的實(shí)例 , 并且是否是其父類型的實(shí)例
function Aoo(){}
function Foo(){}
Foo.prototype = new Aoo();//JavaScript 原型繼承
var foo = new Foo();
console.log(foo instanceof Foo)//true
console.log(foo instanceof Aoo)//true
上面的代碼中是判斷了一層繼承關(guān)系中的父類,在多層繼承關(guān)系中,instanceof 運(yùn)算符同樣適用。
你真的了解 instanceof 操作符嗎?
看了上面的代碼示例,是不是覺得 instanceof 操作符很簡單,下面來看點(diǎn)復(fù)雜的用法。
清單 4. instanceof 復(fù)雜用法
console.log(Object instanceof Object);//true console.log(Function instanceof Function);//true console.log(Number instanceof Number);//false console.log(String instanceof String);//false console.log(Function instanceof Object);//true console.log(Foo instanceof Function);//true console.log(Foo instanceof Foo);//false
看了上面的代碼是不是又暈頭轉(zhuǎn)向了?為什么 Object 和 Function instanceof 自己等于 true,而其他類 instanceof 自己卻又不等于 true 呢?如何解釋?要想從根本上了解 instanceof 的奧秘,需要從兩個(gè)方面著手:1,語言規(guī)范中是如何定義這個(gè)運(yùn)算符的。2,JavaScript 原型繼承機(jī)制。
清單 5. JavaScript instanceof 運(yùn)算符代碼
function instance_of(L, R) {//L 表示左表達(dá)式,R 表示右表達(dá)式
var O = R.prototype;// 取 R 的顯示原型
L = L.__proto__;// 取 L 的隱式原型
while (true) {
if (L === null)
return false;
if (O === L)// 這里重點(diǎn):當(dāng) O 嚴(yán)格等于 L 時(shí),返回 true
return true;
L = L.__proto__;
}
}
清單 6. Object instanceof Object
// 為了方便表述,首先區(qū)分左側(cè)表達(dá)式和右側(cè)表達(dá)式 ObjectL = Object, ObjectR = Object; // 下面根據(jù)規(guī)范逐步推演 O = ObjectR.prototype = Object.prototype L = ObjectL.__proto__ = Function.prototype // 第一次判斷 O != L // 循環(huán)查找 L 是否還有 __proto__ L = Function.prototype.__proto__ = Object.prototype // 第二次判斷 O == L // 返回 true
清單 7. Function instanceof Function
// 為了方便表述,首先區(qū)分左側(cè)表達(dá)式和右側(cè)表達(dá)式 FunctionL = Function, FunctionR = Function; // 下面根據(jù)規(guī)范逐步推演 O = FunctionR.prototype = Function.prototype L = FunctionL.__proto__ = Function.prototype // 第一次判斷 O == L // 返回 true
清單 8. Foo instanceof Foo
// 為了方便表述,首先區(qū)分左側(cè)表達(dá)式和右側(cè)表達(dá)式 FooL = Foo, FooR = Foo; // 下面根據(jù)規(guī)范逐步推演 O = FooR.prototype = Foo.prototype L = FooL.__proto__ = Function.prototype // 第一次判斷 O != L // 循環(huán)再次查找 L 是否還有 __proto__ L = Function.prototype.__proto__ = Object.prototype // 第二次判斷 O != L // 再次循環(huán)查找 L 是否還有 __proto__ L = Object.prototype.__proto__ = null // 第三次判斷 L == null // 返回 false
簡析 instanceof 在 Dojo 繼承機(jī)制中的應(yīng)用
在 JavaScript 中,是沒有多重繼承這個(gè)概念的,就像 Java 一樣。但在 Dojo 中使用 declare 聲明類時(shí),是允許繼承自多個(gè)類的。下面以 Dojo 1.6.1 為例。
清單 9. Dojo 中多重繼承
dojo.declare("Aoo",null,{});
dojo.declare("Boo",null,{});
dojo.declare("Foo",[Aoo,Boo],{});
var foo = new Foo();
console.log(foo instanceof Aoo);//true
console.log(foo instanceof Boo);//false
console.log(foo.isInstanceOf(Aoo));//true
console.log(foo.isInstanceOf(Boo));//true
上面的示例中,F(xiàn)oo 同時(shí)繼承自 Aoo 和 Boo,但當(dāng)使用 instanceof 運(yùn)算符來檢查 foo 是否是 Boo 的實(shí)例時(shí),返回的是 false。實(shí)際上,在 Dojo 的內(nèi)部,F(xiàn)oo 仍然只繼承自 Aoo,而通過 mixin 機(jī)制把 Boo 類中的方法和屬性拷貝到 Foo 中,所以當(dāng)用 instanceof 運(yùn)算符來檢查是否是 Boo 的實(shí)例時(shí),會(huì)返回 false。所以 Dojo 為每個(gè)類的實(shí)例添加了一個(gè)新的方法叫 isInstanceOf,用這個(gè)方法來檢查多重繼承。
相關(guān)文章
溫故知新——JavaScript中的字符串連接問題最全總結(jié)(推薦)
這篇文章主要介紹了JS中的字符串連接問題,ECMAScript 中最常見的一個(gè)問題是字符串連接的性能。在調(diào)用 join() 方法時(shí)才會(huì)發(fā)生連接操作,具體操作步驟大家可查看下文的詳細(xì)講解,感興趣的小伙伴們可以參考一下。2017-08-08
javascript數(shù)組里的27個(gè)方法總合詳解
這篇文章主要為大家詳細(xì)介紹了javascript數(shù)組里的方法27個(gè)總合,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02
JavaScript中二維數(shù)組的創(chuàng)建技巧
二維數(shù)組本質(zhì)上是以數(shù)組作為數(shù)組元素的數(shù)組,即"數(shù)組的數(shù)組",類型說明符 數(shù)組名[常量表達(dá)式][常量表達(dá)式]。二維數(shù)組又稱為矩陣,行列數(shù)相等的矩陣稱為方陣。對稱矩陣a[i][j] = a[j][i],對角矩陣:n階方陣主對角線外都是零元素2021-11-11
JavaScript中用sort()方法對數(shù)組元素進(jìn)行排序的操作
這篇文章主要介紹了JavaScript中用sort()方法對數(shù)組元素進(jìn)行排序的操作,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-06-06
javascript實(shí)現(xiàn)滑動(dòng)解鎖功能
這篇文章主要介紹了javascript實(shí)現(xiàn)滑動(dòng)解鎖功能的方法及示例,效果非常棒,需要的朋友可以參考下2014-12-12

