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设计