Javascript 类型判断

判断一个变量的类型一直是许多开发者困扰的问题,没有去深究这个问题的我,直到工作一年,都没能在脑内蹦现出一个可以全面而快速的判断类型方法。

一些不太全面的判断方法:

  • Array.isArray()
    判断一个值是否是数组
  • instanceof
    Javascript 类型判断_第1张图片
    image.png

a instanceof Array

判断 Array.prototype 是否存在于参数 a 的原型链,等同于判断 Array.prototype === a.__proto__而后者是又能被重新赋值,换句话说这样的判断并不可靠;同时浏览器环境下可能出现多个 frame 或者 window 的交互,如果判断[] instanceof window.frames[0].Array显然要返回 false

  • typeof
    说实话 typeof 只有用来判断 function 或者 undefined 的时候才是优先的考虑,毕竟如下表格( Type 一列表示 typeof 操作符的运算结果)。

    Javascript 类型判断_第2张图片
    image.png

  • Object.prototype.toString
    这种方法是结果较为准确,且可以判断各种类型的方法;初次看到这个用法还是在高程里,用于判断一个对象是否是数组类型的;

Object.prototype.toString.call(array) === '[object Array]'

好奇如何实现,于是我找到了规范,如下图:

Javascript 类型判断_第3张图片
image.png

很明显,这种方法并不检测你是不是 某种类型,而是判断 你是否具有某种特性,以这种方式最终决定返回的类型。

这里的第三步,ToObject 是将基本类型转成对应的引用类型,抹平了1new Number(1)的差异。

Javascript 类型判断_第4张图片
image.png

这里的第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

你可能感兴趣的:(Javascript 类型判断)