- JavaScript重難點(diǎn)實(shí)例精講
- 周雄
- 2345字
- 2020-10-30 15:51:54
1.4.2 typeof運(yùn)算符
typeof運(yùn)算符用于返回操作數(shù)的數(shù)據(jù)類型,有以下兩種使用形式。
typeof operand typeof (operand)
其中operand表示需要返回?cái)?shù)據(jù)類型的操作數(shù),可以是引用類型,也可以是基本數(shù)據(jù)類型。
括號(hào)有的時(shí)候是必須的,如果不加上括號(hào)將會(huì)因?yàn)閮?yōu)先級(jí)的問題得不到我們想要的結(jié)果。
typeof運(yùn)算符在處理不同數(shù)據(jù)類型時(shí)會(huì)得到不同的結(jié)果,圖1-2總結(jié)出了可能的返回值。

圖1-2
針對(duì)圖1-2中不同的數(shù)據(jù)類型,下面總結(jié)了一些使用場(chǎng)景。
1. 處理Undefined類型的值
雖然Undefined類型的值只有一個(gè)undefined,但是typeof運(yùn)算符在處理以下3種值時(shí)都會(huì)返回“undefined”。
· undefined本身。
· 未聲明的變量。
· 已聲明未初始化的變量。
var declaredButUnde?nedVariable; typeof unde?ned === 'unde?ned'; // true typeof declaredButUnde?nedVariable === 'unde?ned'; // true,已聲明未初始化的變量 typeof undeclaredVariable === 'unde?ned'; // true,未聲明的變量
2. 處理Boolean類型的值
Boolean類型的值只有兩個(gè),分別是true和false。typeof運(yùn)算符在處理這兩個(gè)值以及它們的包裝類型時(shí)都會(huì)返回“boolean”,但是不推薦使用包裝類型的寫法。
typeof true === 'boolean'; // true typeof false === 'boolean'; // true typeof Boolean(true) === 'boolean'; // true,不推薦這么寫
3. 處理Number類型的值
對(duì)于Number類型的數(shù)據(jù),可以概括為以下這些值,typeof運(yùn)算符在處理時(shí)會(huì)返回“number”。
· 數(shù)字,如1、123、145。
· Number類型的靜態(tài)變量,如Number.MAX_VALUE、Number.EPSILON等。
· Math對(duì)象的靜態(tài)變量值,如Math.PI、Math.LN2(以e為底,2的對(duì)數(shù))。
· NaN,雖然NaN是Not a Number的縮寫,但它是Number類型的值。
· Infinity和-Infinity,表示的是無窮大和無窮小的數(shù)。
· 數(shù)值類型的包裝類型,如Number(1)、Number(123),雖然它們也會(huì)返回“number”,但是并不推薦這么寫。
通過上述的總結(jié),我們可以快速完成以下這些測(cè)試。
typeof 37 === 'number'; // true typeof 3.14 === 'number'; // true typeof Math.LN2 === 'number'; // true typeof In?nity === 'number'; // true typeof NaN === 'number'; // true typeof Number(1) === 'number'; // true,不推薦這么寫
4. 處理String類型的值
對(duì)于String類型的數(shù)據(jù),可以概括為以下這些值,typeof運(yùn)算符在處理時(shí)會(huì)返回“string”。
· 任何類型的字符串,包括空字符串和非空字符串。
· 返回值為字符串類型的表達(dá)式。
· 字符串類型的包裝類型,例如String('hello')、String('hello' + 'world'),雖然它們也會(huì)返回“String”,但是并不推薦這么寫。
通過上述的總結(jié),我們可以快速完成以下這些測(cè)試。
typeof "" === 'string'; // true typeof "bla" === 'string'; // true typeof (typeof 1) === 'string'; // true,因?yàn)閠ypeof會(huì)返回一個(gè)字符串 typeof String("abc") === 'string'; // true,不推薦這么寫
5. 處理Symbol類型的值
Symbol類型是在ES6中新增的原生數(shù)據(jù)類型,表示一個(gè)獨(dú)一無二的值,typeof運(yùn)算符處理后得到的返回值為“symbol”。
typeof Symbol() === 'symbol'; // true typeof Symbol('foo') === 'symbol'; // true
6. 處理Function類型的值
對(duì)于Function類型的數(shù)據(jù),可以概括為以下這些值,typeof運(yùn)算符在處理時(shí)會(huì)返回“function”。
· 函數(shù)的定義,包括函數(shù)聲明或者函數(shù)表達(dá)式兩種形式。
· 使用class關(guān)鍵字定義的類,class是在ES6中新增的關(guān)鍵字,它不是一個(gè)全新的概念,原理依舊是原型繼承,本質(zhì)上仍然是一個(gè)Function。
· 某些內(nèi)置對(duì)象的特定函數(shù),例如Math.sin()函數(shù)、Number.isNaN()函數(shù)等。
· Function類型對(duì)象的實(shí)例,一般通過new關(guān)鍵字得到。
通過上述的總結(jié),我們可以快速完成以下這些測(cè)試。
var foo = function () {}; function foo2() {} typeof foo === 'function'; // true,函數(shù)表達(dá)式 typeof foo2 === 'function'; // true,函數(shù)聲明 typeof class C{} === 'function'; // true typeof Math.sin === 'function'; // true typeof new Function() === 'function'; // true,new操作符得到Function類型的實(shí)例
7. 處理Object類型的值
對(duì)于Object類型的數(shù)據(jù),可以概括為以下這些值,typeof運(yùn)算符在處理時(shí)會(huì)返回“object”。
· 對(duì)象字面量形式,例如{name: 'kingx'}。
· 數(shù)組,例如[1, 2, 3]和Array(1, 2, 3)。
· 所有構(gòu)造函數(shù)通過new操作符實(shí)例化后得到的對(duì)象,例如new Date()、new function(){},但是new Function(){}除外。
· 通過new操作符得到的基本數(shù)據(jù)類型的包裝類型對(duì)象,如new Boolean(true)、newNumber(1),但不推薦這么寫。
細(xì)心的讀者可能發(fā)現(xiàn)了,與基本數(shù)據(jù)類型的包裝類型相關(guān)的部分,我們都有寫“不推薦這么寫”,這是為什么呢?
因?yàn)樯婕鞍b類型時(shí),使用了new操作符與沒有使用new操作符得到的值在通過typeof運(yùn)算符處理后得到的結(jié)果是不一樣的,很容易讓人混淆。
通過上述的總結(jié),我們可以快速完成以下這些測(cè)試。
typeof {a:1} === 'object'; // true,對(duì)象字面量 typeof [1, 2, 4] === 'object'; // true,數(shù)組 typeof new Date() === 'object'; // true,Date對(duì)象的實(shí)例 // 下面的代碼容易令人迷惑,不要使用! typeof new Boolean(true) === 'object'; // true typeof new Number(1) === 'object'; // true typeof new String("abc") === 'object'; // true
typeof運(yùn)算符的使用在絕大部分情況下都是安全的,但是在ES6以后情況就不一樣了。這里總結(jié)了使用typeof運(yùn)算符時(shí)需要考慮的問題。
1. typeof運(yùn)算符區(qū)分對(duì)待Object類型和Function類型
在Nicholas C.Zakas所著的《JavaScript高級(jí)程序設(shè)計(jì)》一書中講到,從技術(shù)角度講,函數(shù)在ECMAScript中是對(duì)象,不是一種數(shù)據(jù)類型。然而,函數(shù)也確實(shí)有一些特殊的屬性,因此通過typeof運(yùn)算符來區(qū)分函數(shù)和其他對(duì)象是有必要的。
另外,在實(shí)際使用過程中,有必要區(qū)分Object類型和Function類型,而typeof運(yùn)算符就能幫我們實(shí)現(xiàn)。
2. typeof運(yùn)算符對(duì)null的處理
使用typeof運(yùn)算符對(duì)null進(jìn)行處理,返回的是“object”,這是一個(gè)讓大家都感到驚訝的結(jié)果。因?yàn)閚ull是一個(gè)原生類型的數(shù)據(jù),為什么typeof運(yùn)算符會(huì)返回“object”呢?
這是一個(gè)在JavaScript設(shè)計(jì)之初就存在的問題,這里簡(jiǎn)單介紹下。
在JavaScript中,每種數(shù)據(jù)類型都會(huì)使用3bit表示。
· 000表示Object類型的數(shù)據(jù)。
· 001表示Int類型的數(shù)據(jù)。
· 010表示Double類型的數(shù)據(jù)。
· 100表示String類型的數(shù)據(jù)。
· 110表示Boolean類型的數(shù)據(jù)。
由于null代表的是空指針,大多數(shù)平臺(tái)中值為0x00,因此null的類型標(biāo)簽就成了0,所以使用typeof運(yùn)算符時(shí)會(huì)判斷為object類型,返回“object”。
雖然在后面的提案中有提出修復(fù)方案,但是因?yàn)橛绊懨嫣螅圆]有被采納,從而導(dǎo)致這個(gè)問題一直存在。
3. typeof運(yùn)算符相關(guān)語法的括號(hào)
在前文中有講到,括號(hào)有時(shí)是必須存在的,如果不加上括號(hào)則會(huì)因?yàn)閮?yōu)先級(jí)的問題得不到我們想要的結(jié)果。
我們可以通過以下代碼看看加不加括號(hào)在結(jié)果上的差異。
var number = 123; typeof (number + ' hello'); // "string" typeof number + ' hello'; // "number hello"
因?yàn)閠ypeof運(yùn)算符的優(yōu)先級(jí)會(huì)高于字符串拼接運(yùn)算符(+),但是優(yōu)先級(jí)低于小括號(hào)(),所以在未使用括號(hào)時(shí),會(huì)優(yōu)先處理typeof number,返回的是"number",然后與"hello"字符串進(jìn)行拼接,得到結(jié)果"number hello"。
下面是更能體現(xiàn)括號(hào)重要性的例子。
typeof 1 / 0; // "NaN" typeof (1 / 0); // "number"
第一行代碼中,因?yàn)闆]有小括號(hào),實(shí)際會(huì)先運(yùn)行typeof 1,返回的是"number",然后除以0,一個(gè)字符串除以0,得到的是"NaN"。
第二行代碼中,因?yàn)槭褂昧诵±ㄌ?hào),實(shí)際會(huì)先運(yùn)行1/0,得到的是Infinity,而Infinity實(shí)際上為Number類型的值,通過typeof運(yùn)算符處理后,得到的是"number"。
因此在處理某些表達(dá)式時(shí),需要將這些表達(dá)式用括號(hào)括起來以保證先運(yùn)算表達(dá)式,再使用typeof運(yùn)算符進(jìn)行運(yùn)算。
- Access 數(shù)據(jù)庫應(yīng)用教程
- 實(shí)戰(zhàn)Java程序設(shè)計(jì)
- Flask Web開發(fā)入門、進(jìn)階與實(shí)戰(zhàn)
- Python自然語言處理(微課版)
- MySQL數(shù)據(jù)庫基礎(chǔ)實(shí)例教程(微課版)
- 快速念咒:MySQL入門指南與進(jìn)階實(shí)戰(zhàn)
- 程序是怎樣跑起來的(第3版)
- 區(qū)塊鏈技術(shù)與應(yīng)用
- Node Cookbook(Second Edition)
- Mastering React
- 動(dòng)手打造深度學(xué)習(xí)框架
- UML2面向?qū)ο蠓治雠c設(shè)計(jì)(第2版)
- 算法圖解
- Python硬件編程實(shí)戰(zhàn)
- TypeScript全棧開發(fā)