面试题:JavaScript 中判断数据类型的方式有哪些?

在 JavaScript 中,由于其动态类型和弱类型的特性,准确判断数据类型是开发中的常见需求。以下是几种主要的判断方式,各有优缺点和适用场景。


1. typeof 操作符

最常用的基础类型判断方法。

  • 语法:typeof value 或 typeof(value)
  • 返回值:一个表示数据类型的小写字符串。
值typeof 结果说明
undefined"undefined"✅
null"object"❌ 经典陷阱! null 是原始值,但 typeof null 返回 "object"。
true / false"boolean"✅
123, 3.14, NaN"number"✅
"hello""string"✅
Symbol('id')"symbol"✅ (ES6)
function() {}"function"✅
{} / [] / new Date() / new RegExp()"object"✅ 但无法区分具体对象类型。

优点:

  • 简单快捷,适合判断原始类型(除 null 外)和函数。

缺点:

  • 无法区分 null 和其他对象(都返回 "object")。
  • 无法区分不同类型的对象(如数组、日期、正则等,都返回 "object")。

示例:

typeof "hello";     // "string"
typeof 42;          // "number"
typeof true;        // "boolean"
typeof undefined;   // "undefined"
typeof null;        // "object" (问题!)
typeof [];          // "object" (问题!)
typeof function(){}; // "function"

2. Object.prototype.toString.call()

最准确、最推荐的通用类型判断方法。

  • 语法:Object.prototype.toString.call(value)
  • 原理:调用对象的 toString 方法,返回一个标准格式的字符串 [object Type]。
值Object.prototype.toString.call() 结果
null"[object Null]"
undefined"[object Undefined]"
"hello""[object String]"
42"[object Number]"
true"[object Boolean]"
[]"[object Array]"
{}"[object Object]"
new Date()"[object Date]"
/abc/"[object RegExp]"
function() {}"[object Function]"
Symbol('id')"[object Symbol]"

优点:

  • 能准确区分所有内置类型,包括 null 和各种对象。
  • 是判断数据类型最可靠的方法。

缺点:

  • 语法稍长。

封装工具函数:

function getType(value) {
  return Object.prototype.toString.call(value).slice(8, -1); // 提取 "Type"
}

getType([]);        // "Array"
getType(new Date()); // "Date"
getType(null);      // "Null"
getType(/abc/);     // "RegExp"

3. instanceof 操作符

用于判断一个对象是否是某个构造函数的实例。

  • 语法:object instanceof Constructor
  • 原理:通过检查构造函数的 prototype 属性是否出现在对象的原型链中。

示例:

[] instanceof Array;        // true
[] instanceof Object;       // true (数组也是对象)
new Date() instanceof Date; // true
new Date() instanceof Object; // true
function() {} instanceof Function; // true

优点:

  • 适合判断自定义对象或明确知道构造函数的类型。

缺点:

  • 对于原始类型无效("hello" instanceof String 返回 false,因为原始值不是对象)。
  • 在跨 iframe 等场景下可能失效(不同全局环境中的构造函数不同)。
  • 无法判断 null 和 undefined。

4. Array.isArray()

专门用于判断是否为数组的静态方法。

  • 语法:Array.isArray(value)
  • 返回值:true 或 false。

示例:

Array.isArray([]);     // true
Array.isArray({});     // false
Array.isArray("hello"); // false

优点:

  • 判断数组的首选方法,比 instanceof 更可靠(不受 iframe 影响)。
  • 语义清晰。

缺点:

  • 只能判断数组。

5. 其他方法(不推荐或有限使用)

  • constructor 属性:
[].constructor === Array; // true

问题:constructor 属性可以被重写,不可靠。

  • === null 或 === undefined:
value === null;      // 判断 null
  value === undefined; // 判断 undefined

适用场景:直接判断 null 或 undefined。

  • isNaN():判断值是否为 NaN。
  • isFinite():判断值是否为有限数。

总结与最佳实践

方法适用场景推荐度
typeof判断原始类型(除 null)和函数⭐⭐⭐⭐
Object.prototype.toString.call()通用、精确判断所有类型⭐⭐⭐⭐⭐
instanceof判断对象是否为某个构造函数的实例⭐⭐⭐
Array.isArray()专门判断数组⭐⭐⭐⭐⭐
直接比较 (=== null)判断 null 或 undefined⭐⭐⭐⭐

推荐策略:

  1. 判断数组:使用 Array.isArray(value)。
  2. 判断 null 或 undefined:直接使用 value === null 或 value == null(== 可同时判断 null 和 undefined)。
  3. 通用精确判断:使用 Object.prototype.toString.call(value) 封装一个 getType 工具函数。
  4. 快速判断原始类型:使用 typeof,但注意 null 的陷阱。

掌握这些方法的区别和适用场景,能让你在 JavaScript 开发中更准确地处理类型判断。

THE END
喜欢就支持一下吧
点赞5 分享