前端面试-JavaScript 数据类型检测全解

目录

一、基础检测方法

二、方法深度解析

1. typeof 运算符

2. instanceof 运算符

3. 终极检测方案

三、特殊场景检测方案

四、手写实现原理

1. 通用类型检测函数

2. 改进版数组检测(兼容旧浏览器)

五、常见面试陷阱

六、最佳实践指南

七、扩展知识

总结


一、基础检测方法
方法能力范围经典案例注意事项
typeof检测基本数据类型(除 nulltypeof 'str' → 'string'typeof null → 'object'(历史遗留问题)
instanceof检测对象原型链[] instanceof Array → true跨窗口对象检测失效(如iframe)
Object.prototype.toString.call()精确检测所有类型toString.call([]) → '[object Array]'需配合 call 改变 this 指向

二、方法深度解析
1. typeof 运算符
  • 返回值类型:返回类型字符串

    typeof 42;          // "number"
    typeof 'text';      // "string"
    typeof true;        // "boolean"
    typeof undefined;   // "undefined"
    typeof Symbol();    // "symbol"
    typeof 10n;         // "bigint" (ES2020+)
    typeof function(){};// "function"
    typeof {};          // "object"
    typeof [];          // "object" (缺陷)
    typeof null;        // "object" (著名陷阱)

2. instanceof 运算符
  • 原型链检测机制

    function Car() {}
    const myCar = new Car();
    myCar instanceof Car;     // true
    myCar instanceof Object;  // true(原型链追溯)

  • 跨窗口问题

    // 不同iframe中的Array构造函数不共享原型链
    iframe.contentWindow.Array !== window.Array;
    iframeArray instanceof Array; // false

3. 终极检测方案

const typeCheck = obj => {
  return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
};

typeCheck([]);        // 'array'
typeCheck(new Date);  // 'date'
typeCheck(null);      // 'null'
typeCheck(/regex/);   // 'regexp'
typeCheck(Symbol());  // 'symbol'

三、特殊场景检测方案
检测需求实现方案示例
数组检测Array.isArray() (ES5+)Array.isArray([1,2]) → true
NaN检测Number.isNaN() (ES6+)Number.isNaN(NaN) → true
纯对象检测组合检测obj.constructor === Object && Object.getPrototypeOf(obj) === Object.prototype
Promise检测obj instanceof Promisep instanceof Promise
Buffer检测Buffer.isBuffer() (Node.js)Buffer.isBuffer(buffer)

四、手写实现原理
1. 通用类型检测函数

function getType(obj) {
  // 处理 null 的特殊情况
  if (obj === null) return 'null';
  
  // 处理基础类型(除 symbol)
  const type = typeof obj;
  if (type !== 'object') return type;

  // 处理引用类型
  const typeStr = Object.prototype.toString.call(obj);
  return typeStr.slice(8, -1).toLowerCase();
}
2. 改进版数组检测(兼容旧浏览器)

const isArray = (function() {
  if (typeof Array.isArray === 'function') {
    return Array.isArray;
  }
  return function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  };
})();

五、常见面试陷阱
  1. typeof 的边界情况

    typeof NaN;           // "number"(需用 Number.isNaN 判断)
    typeof document.all;  // "undefined" (历史遗留特性)

  2. 包装对象检测

    const str = new String('test');
    typeof str;          // "object"
    str instanceof String; // true

  3. 修改对象 [[Class]] 属性

    const obj = {};
    Object.prototype.toString.call(obj); // [object Object]
    obj[Symbol.toStringTag] = 'Custom';
    Object.prototype.toString.call(obj); // [object Custom]


六、最佳实践指南
  1. 基础类型检测:优先使用 typeof

  2. 数组检测:统一使用 Array.isArray()

  3. 精确类型判断:使用 Object.prototype.toString.call()

  4. 构造函数检测:慎用 instanceof(注意原型链污染风险)

  5. 特殊值检测

    • null → obj === null

    • undefined → obj === void 0

    • NaN → Number.isNaN()


七、扩展知识
  1. ES6 新增类型检测

    const set = new Set();
    Object.prototype.toString.call(set); // [object Set]
    
    const map = new Map();
    Object.prototype.toString.call(map); // [object Map]

  2. BigInt 检测

    typeof 10n; // "bigint"

  3. 异步函数检测

    async function fn() {}
    Object.prototype.toString.call(fn); // [object AsyncFunction]


总结

掌握数据类型检测是JavaScript开发的基本功,针对不同场景选择合适的检测方案:

  • 快速判断基本类型 → typeof

  • 原型链关系验证 → instanceof

  • 精确类型识别 → Object.prototype.toString.call()

  • 特定类型优化 → 专用方法(如 Array.isArray)

理解这些方法的实现原理和边界条件,能够帮助开发者写出更健壮的代码,在面试中也能从容应对相关问题的深度追问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值