详解js类型判断

作者:极速慢跑时间:2026-10-22 14:36:32浏览:331

本文深入解析JavaScript中类型判断的演进过程。首先指出typeof在null处理上的局限,随后介绍基于Object.prototype.toString的标准实现。接着通过闭包缓存和jQuery源码思路优化性能,并补充了window对象与DOM元素的判断方法,提供高效且准确的类型检测方案。

JavaScript类型判断基础

在JavaScript的类型转换机制中,typeof运算符存在一个已知缺陷:它会将null识别为object类型。此外,typeof返回的类型信息较为有限。为了获得更准确的结果,通常采用Object.prototype.toString方法来实现类型判断。

类型检测的演进

第一版


function isArray(value){
  return Object.prototype.toString.call(value) === "[object Array]";
}

function isFunction(value){
  return Object.prototype.toString.call(value) === "[object Function]";
}

然而,如果采用逐一判断数组、函数、对象等类型的方式,代码显得过于繁琐且过程化,缺乏简洁性。

第二版

为了提升使用体验,我们设计type(obj)函数以返回对应的类型字符串。考虑到typeof返回的是小写形式,我们的实现也保持一致,返回小写的标准类型名。


function type(obj){
  // -1 代表截止到倒数一位
  return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase()
}

type([]) // "array"

虽然这种方式可行,但每次调用时都需要对判断结果进行slice截取和toLowerCase转换,这在频繁调用时可能带来性能损耗。由于需要判断的类型种类有限,我们可以利用对象提前缓存可能的结果,从而优化性能。

第三版


//将types放外面 而不是放在type函数里面, 利用闭包,优化性能,不用每次判断都声明一次typess
var types = {
  '[object Function]': 'function',
  '[object Number]': 'number',
  ...
}

function type(obj) {
  var str = Object.prototype.toString.call(obj)
  return types[str]
}

当然,上述types对象的定义方式还可以进一步优化,以借鉴更成熟的源码实现。


// 参考自jquery源码
var types = {}
当然也可以直接用数组存储
"Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function(e,i){
  types [ "[object " + e + "]" ] = e.toLowerCase();
}) ;

特殊对象与DOM元素判断

判断window对象

利用window对象的window属性等于自身的特性进行判断。


function isWindow( obj ) {
  // obj !== undefined 是为了防止没传参数的时候后面报错
  // Uncaught TypeError: Cannot read property 'window' of undefined的错误
  
  return obj !== undefined && obj === obj.window;
}

判断是不是dom元素


isElement = function(obj) {
  return !!(obj && obj.nodeType === 1);
}

作者最新文章