聯繫
這三者都可以用來判斷一個對象的類型
let now = new Date()
now instanceof Date // 輸出: true
now.constructor == Date // 輸出: true
typeof 'hello' // 輸出: string
typeof('hello') // 高版本的 js 支持這種寫法。輸出: string
看起來是這樣的:
- typeof 返回一個對象的類型的名字,即返回一個字符串
- instanceof 用來判斷左邊的值是否屬於右邊的類型,返回布爾值 true 或 false(嚴謹地說是:“左值是否爲右值的實例”)
- constructor 則比較單純,返回當前對象的構造方法
這看起來很是理所當然,但是下面的這幾行代碼:
let now = new Date()
async function fn() {}
typeof(now) == 'date' // 輸出: ?
'hello' instanceof String // 輸出: ?
fn.constructor == Function // 輸出: ?
沒錯,這些輸出全是 false
如果你已經知道這三個輸出都是 false,則本篇筆記對你就沒有任何幫助了
typeof
寫法
首先對 typeof 的寫法做一個建議:一種是函數寫法 typeof('hello')
,另一種是操作符寫法typeof 'hello'
。我建議能用函數寫法就用函數寫法,下面這行代碼讀起來往往會使人不自信:
typeof 'hello' == 'string'
是“判斷'hello'
的類型是否爲'string'
?“ (即(typeof 'hello') == 'string'
)
還是“獲取'hello' == 'string'
的類型的名字是什麼?”(即typeof ('hello' == 'string')
)
當然,如果你對這些優先級爛熟於心,一目瞭然,似乎就沒什麼影響。但是如果 typeof
後面拖了一個很長的表達式呢?如果跟你合作的同事對此並不熟悉呢?
用法
typeof 返回當前對象的類型的名字,沒錯。
但是let a = new Date()
中的 a
不僅是一個 Date
,同時也是一個 Object
(js 中萬物皆對象,而 Object 是所有對象的共同的父類 )。
另外,typeof 'hello'
返回'string'
('hello'
的確是字符串);
而typeof new String('hello')
則返回'object'
(new String('hello')
也的確是一個Object
啊)。
而 mdn 對 typeof
的返回值有一個對照表,如下圖:
這樣,看似就比較明確了,只是難記億點點,可是……
不同的運行環境產生的結果還不一樣,比如下面這個
typeof /s/
在火狐瀏覽器裏返回'object'
,而谷歌返回'function'
。
這就……
所幸,還有instanceof
和 constructor
instanceof
mdn 對 instanceof 的解釋是“右邊的值是否在左邊的值的原型鏈上“,即:判斷左值是否爲右值(類)的實例。可以這樣理解:如果“小咪”是一隻貓的話,那“小咪”肯定也是一隻“動物”。也就是說 instanceof
就可以理解爲”是否屬於“
比如,let now = new Date()
,中,now
是一個 Date
對象,同時也是一個 Object
。所以下面的輸出全爲true
let now = new Date()
now instanceof Date // 輸出: ?
now instanceof Object // 輸出: ?
let fn = async function(){}
fn instanceof Function // 輸出: ?
fn instanceof Object // 輸出: ?
但是字符串在 js 中是一類特殊的東西,instanceof
對字符串就不太友好。
如果我不讓你想象一頭大象,不要想象大象的鼻子,那你肯定忍不住會想到大象、大象的鼻子,所以這裏就不再放錯誤示例了。應該記得:不要對 String 使用 instanceof
處理 String
可以使用 Constructor
。
constructor
constructor 簡單粗暴,返回當前對象的構造方法,而一個對象的構造方法就是這個對象的類
比如:
let now = new Date()
now.constructor == Date // true
now.constructor == Object // false
'hello'.constructor == String // true
new String('hello').constructor == String // true
'hello'.constructor == Object // false
雖然 Object
是 Date
和 String
的父類,但 now
的構造方法是明確的,就是 Date
,跟父類無關;'hello'
則同理。
小結
- typeof:不用,就不會迷惑,就不會出錯
- instanceof:表示“是否屬於(類和父類)”,但對字符串不太友好
- constructor:返回當前值的構造函數,精準(只用於判斷類,而不能用於判斷父類)
- 一般情況用
instanceof
,字符串用constructor