Javascript 类型判断
判断一个变量的类型一直是许多开发者困扰的问题,没有去深究这个问题的我,直到工作一年,都没能在脑内蹦现出一个可以全面而快速的判断类型方法。
一些不太全面的判断方法:
-
Array.isArray()
判断一个值是否是数组 -
instanceof
image.png
a instanceof Array
判断 Array.prototype 是否存在于参数 a 的原型链,等同于判断 Array.prototype === a.__proto__
而后者是又能被重新赋值,换句话说这样的判断并不可靠;同时浏览器环境下可能出现多个 frame 或者 window 的交互,如果判断[] instanceof window.frames[0].Array
显然要返回 false
。
-
typeof
image.png
说实话 typeof 只有用来判断 function 或者 undefined 的时候才是优先的考虑,毕竟如下表格( Type 一列表示 typeof 操作符的运算结果)。
-
Object.prototype.toString
这种方法是结果较为准确,且可以判断各种类型的方法;初次看到这个用法还是在高程里,用于判断一个对象是否是数组类型的;
Object.prototype.toString.call(array) === '[object Array]'
好奇如何实现,于是我找到了规范,如下图:
很明显,这种方法并不检测你是不是 某种类型,而是判断 你是否具有某种特性,以这种方式最终决定返回的类型。
这里的第三步,ToObject 是将基本类型转成对应的引用类型,抹平了1
和new Number(1)
的差异。
这里的第15步, Get
方法是取对象 O 的 @@toStringTag 键的值,我们可以看到上述类型没有出现 Symbol ,Promise 等内置的其他一些类。
许多内置的 JavaScript 对象类型即便没有 toStringTag 属性,也能被 toString() 方法识别并返回特定的类型标签,另外一些对象类型则不然,toString() 方法能识别它们是因为引擎为它们设置好了 toStringTag 标签:
Object.prototype.toString.call(new Map()); // "[object Map]" Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"
引自:Symbol.toStringTag
步骤16,如果该类型没有定义 toStringTag 值或值不是字符串 ,那么就令 tag 为 builtin Tag。
看起来要得到 javascript 一个对象的类型并不是一件轻松的事情呢(笑)。
相关阅读:
鸭子类型
JavaScript-Garden