typeof
操做符(還有 instanceof
)多是 Javascript
設計中最大缺陷,由於它幾乎是徹底破損的。因爲 typeof
用法與調用函數的語法類似,所以常被誤覺得是函數調用,實際上並不存在名爲 typeof
的函數,typeof
只是一個操做符而已。
儘管 instanceof
仍然還有少數的應用場景,typeof
則只有一個實際的用途,但這個用途不能用來檢測對象的類型。git
Value Class Type ------------------------------------- "foo" String string new String("foo") String object 1.2 Number number new Number(1.2) Number object true Boolean boolean new Boolean(true) Boolean object new Date() Date object new Error() Error object [1,2,3] Array object new Array(1, 2, 3) Array object new Function("") Function function /abc/g RegExp object (function in Nitro/V8) new RegExp("meow") RegExp object (function in Nitro/V8) {} Object object new Object() Object object
在上述表格中,Type
列表示 typeof
操做符的結果。而 Class
列則表示對象內部的 [[Class]]
屬性。
爲了得到 [[Class]]
屬性,咱們須要使用 Object.prototype
的 toString
方法。github
文檔中明確地給出了得到 [[Class]]
屬性的途徑,就是使用 Object.prototype.toString
。segmentfault
function is(type, obj) { var clas = Object.prototype.toString.call(obj).slice(8, -1); return obj !== undefined && obj !== null && clas === type; } is('String', 'test'); // true is('String', new String('test')); // true
上例中,Object.prototype.toString
被調用,this
被設置指向須要獲取其 [[Class]]
屬性值的對象。ide
文檔定義:
[[Class]]
屬性的值只多是下列字符串:Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String
。
對null
和undefined
調用Object.prototype.toString
方法時, 其返回值將由Object
變成了Null
和Undefined
。函數
typeof foo !== 'undefined'
上述語句將會測試變量 foo
已定義與否,若是未定義而引用 foo
將會拋出 ReferenceError
錯誤,這其實是 typeof
用處最大的地方。測試
爲了檢測一個對象的類型,最可靠的方法就是使用 Object.prototype.toString
,正如第一個表格上的內容,typeof
操做符並不能返回確切的對象類型,可是咱們可使用 typeof
操做符常常會被用來判斷變量是否認義。
其實 typeof
操做符還能夠被用來測試變量是否爲函數,@humphry 前輩的回答進一步豐富了 typeof
的用途:this
《如何正確判斷js數據類型》prototype
http://bonsaiden.github.io/JavaScript-Garden/#types.typeof設計