JavaScript中typeof和instanceof深入詳解
這次主要說說javascript的型別判斷函式typeof和判斷建構函式原型instanceof的用法和注意的地方。
typeof
先來說說typeof吧。首先需要注意的是,typeof方法返回一個字串,來表示資料的型別。
語法講解
我們先看看各個資料型別對應typeof的值:
資料型別 | Type |
---|---|
Undefined | “undefined” |
Null | “object” |
布林值 | “boolean” |
數值 | “number” |
字串 | “string” |
Symbol (ECMAScript 6 新增) | “symbol” |
宿主物件(JS環境提供的,比如瀏覽器) | Implementation-dependent |
函式物件 | “function” |
任何其他物件 | “object” |
再看看具體的例項:
// Numbers typeof 37 === 'number'; typeof 3.14 === 'number'; typeof Math.LN2 === 'number'; typeof Infinity === 'number'; typeof NaN === 'number'; // 儘管NaN是"Not-A-Number"的縮寫,意思是"不是一個數字" typeof Number(1) === 'number'; // 不要這樣使用! // Strings typeof "" === 'string'; typeof "bla" === 'string'; typeof (typeof 1) === 'string'; // typeof返回的肯定是一個字串 typeof String("abc") === 'string'; // 不要這樣使用! // Booleans typeof true === 'boolean'; typeof false === 'boolean'; typeof Boolean(true) === 'boolean'; // 不要這樣使用! // Symbols typeof Symbol() === 'symbol'; typeof Symbol('foo') === 'symbol'; typeof Symbol.iterator === 'symbol'; // Undefined typeof undefined === 'undefined'; typeof blabla === 'undefined'; // 一個未定義的變數,或者一個定義了卻未賦初值的變數 // Objects typeof {a:1} === 'object'; // 使用Array.isArray或者Object.prototype.toString.call方法可以從基本的物件中區分出陣列型別 typeof [1, 2, 4] === 'object'; typeof new Date() === 'object'; // 下面的容易令人迷惑,不要這樣使用! typeof new Boolean(true) === 'object'; typeof new Number(1) ==== 'object'; typeof new String("abc") === 'object'; // 函式 typeof function(){} === 'function'; typeof Math.sin === 'function';
我們會發現一個問題,就是typeof來判斷資料型別其實並不準確。比如陣列、正則、日期、物件的typeof返回值都是object,這就會造成一些誤差。
所以在typeof判斷型別的基礎上,我們還需要利用Object.prototype.toString方法來進一步判斷資料型別。
我們來看看在相同資料型別的情況下,toString方法和typeof方法返回值的區別:
資料 | toString | typeof |
---|---|---|
“foo” | String | string |
new String(“foo”) | String | object |
new Number(1.2) | Number | object |
true | Boolean | boolean |
new Boolean(true) | Boolean | object |
new Date() | Date | object |
new Error() | Error | object |
new Array(1, 2, 3) | Array | object |
/abc/g | RegExp | object |
new RegExp(“meow”) | RegExp | object |
可以看到利用toString方法可以正確區分出Array、Error、RegExp、Date等型別。
所以我們一般通過該方法來進行資料型別的驗證
真題檢測
但是既然今天說到了typeof,那這裡就列出幾道題目,來看看自己是否真正掌握了typeof的用法。
第一題:
var y = 1, x = y = typeof x; x;
第二題:
(function f(f){ return typeof f(); })(function(){ return 1; });
第三題:
var foo = { bar: function() { return this.baz; }, baz: 1 }; (function(){ return typeof arguments[0](); })(foo.bar);
第四題:
var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)();
第五題:
var f = (function f(){ return "1"; }, function g(){ return 2; })(); typeof f;
第六題:
var x = 1; if (function f(){}) { x += typeof f; } x;
第七題:
(function(foo){ return typeof foo.bar; })({ foo: { bar: 1 } });
下面公佈答案了,這七題的答案分別是:
"undefined","number","undefined","undefined","number","1undefined","undefined"
做對了幾道呢?是不是很大的困惑呢?這幾題雖然都有typeof,但是考察了很多javascript的基礎噢。下面我們來一一詳解。
第一題:
var y = 1, x = y = typeof x; x;//"undefined"
表示式是從右往左的,x由於變數提升,型別不是null,而是undefined,所以x=y=”undefined”。
變數提升我在這篇文章中提到過,可以看看。
第二題:
(function f(f){ return typeof f();//"number" })(function(){ return 1; });
傳入的引數為f也就是function(){ return 1; }這個函式。通過f()執行後,得到結果1,所以typeof 1返回”number”。這道題很簡單,主要是區分f和f()。
第三題:
var foo = { bar: function() { return this.baz; }, baz: 1 }; (function(){ return typeof arguments[0]();//"undefined" })(foo.bar);
這一題考察的是this的指向。this永遠指向函式執行時的上下文,而不是定義時的(ES6的箭頭函式不算)。當arguments執行時,this已經指向了window物件。所以是”undefined”。對this執行不熟悉的同學可以看看這篇文章:深入理解this,對剛剛提到的箭頭函式感興趣的同學可以看看初步探究ES6之箭頭函式。
第四題:
var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)();//undefined
如果上面那一題做對了,那麼這一題也應該不會錯,同樣是this的指向問題。
第五題:
var f = (function f(){ return "1"; }, function g(){ return 2; })(); typeof f;//"number"
這一題比較容易錯,因為我在遇到這道題之前也從來沒有遇到過javascript的分組選擇符。什麼叫做分組選擇符呢?舉一個例子就會明白了:
var a = (1,2,3); document.write(a);//3,會以最後一個為準
所以上面的題目會返回2,typeof 2當然是”number”啦。
第六題:
var x = 1; if (function f(){}) { x += typeof f; } x;//"1undefined"
這是一個javascript語言規範上的問題,在條件判斷中加入函式宣告。這個宣告語句本身沒有錯,也會返回true,但是javascript引擎在搜尋的時候卻找不到該函式。所以結果為”1undefined”。
第七題:
(function(foo){ return typeof foo.bar; })({ foo: { bar: 1 } });
這題其實是一個考察心細程度的題目。形參的foo指向的是{ foo: { bar: 1 } }這個整體。相信這麼說就明白了。
好啦。上面的題目都是很好的資源噢。
instanceof
接下來該說說instanceof方法了。instanceof運算子可以用來判斷某個建構函式的prototype屬性是否存在於另外一個要檢測物件的原型鏈上。
如果對原型不太瞭解,可以看看深入理解原型。
下面我們看看instanceof的例項:
// 定義建構函式 function C(){} function D(){} var o = new C(); // true,因為 Object.getPrototypeOf(o) === C.prototype o instanceof C; // false,因為 D.prototype不在o的原型鏈上 o instanceof D; 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
但是這裡我們需要注意一個問題:
function f(){ return f; } document.write(new f() instanceof f);//false function g(){} document.write(new g() instanceof g);//true
第一個為什麼返回false呢?因為建構函式的原型被覆蓋了,我們可以看看new f和new g的區別:
相關文章
- js中的typeof和instanceof和===JS
- instanceof和typeof的區別
- 深入瞭解typeof與instanceof的使用場景及注意事項
- 淺談 instanceof 和 typeof 的實現原理
- JavaScript instanceof 運算子深入剖析JavaScript
- 深入理解javascript原型和閉包(5)——instanceofJavaScript原型
- javascript中的typeof和型別判斷JavaScript型別
- JavaScript之原型深入詳解JavaScript原型
- typeof返回值詳解
- JavaScript中Typeof返回的結果JavaScript
- typeof、instanceof與isPrototypeOf()的差異與聯絡
- JavaScript instanceofJavaScript
- JavaScript之this指標深入詳解JavaScript指標
- js--typeof 和 instanceof 判斷資料型別的區別及開發中的使用JS資料型別
- js中typeof用法詳細介紹JS
- JavaScript typeof 運算子JavaScript
- JavaScript中的this詳解JavaScript
- 詳解JavaScript中的thisJavaScript
- 深入瞭解JavaScript中的物件JavaScript物件
- JS-資料型別- typeof/instanceof/Object.prototype.toStringJS資料型別Object
- 深入詳解SQL中的NullSQLNull
- Blocks深入理解和詳解BloC
- 深入瞭解 JavaScript 中的 for 迴圈JavaScript
- JavaScript中 Map 物件詳解JavaScript物件
- JavaScript 中 Property 和 Attribute 的區別詳解JavaScript
- 深入理解typeof操作符
- 深入Oracle的left join中on和where的區別詳解Oracle
- 重學javascript基礎-typeofJavaScript
- javascript typeof undefined 返回值JavaScriptUndefined
- javascript中的Event Loop詳解JavaScriptOOP
- JavaScript 中的遍歷詳解JavaScript
- Javascript中this關鍵字詳解JavaScript
- 詳解Javascript 中的this指標JavaScript指標
- 詳解Javascript中的Object物件JavaScriptObject物件
- 深入理解JavaScript中的WeakMap和WeakSetJavaScript
- javascript instanceof的原型介紹JavaScript原型
- javascript原型和原型鏈詳解JavaScript原型
- JavaScript——深入瞭解thisJavaScript