JS 类型判断方法

常用四种:typeof、instanceof、constructor、Object.prototype.toString.call()。

1. typeof

typeof 123;          // 'number'
typeof 'abc';        // 'string'
typeof true;         // 'boolean'
typeof undefined;    // 'undefined'
typeof null;         // 'object'(历史 bug)
typeof {};           // 'object'
typeof [];           // 'object'
typeof function () {}; // 'function'

2. instanceof

检测构造函数的 prototype 是否出现在实例的原型链上。

[] instanceof Array;            // true
[] instanceof Object;           // true
({}) instanceof Object;         // true

局限:跨窗口 / 跨 iframe 时原型链不共享,结果可能不准;对基本类型返回 false。

3. constructor

当一个函数 F 被定义时,JS 引擎会为 F.prototype 添加一个 constructor 属性,指向 F 自身。new F() 产生的实例沿原型链继承这个 constructor,所以 f.constructor === F。

function F() {}
const f = new F();
f.constructor === F; // true

注意:

  1. null 和 undefined 是无效对象,没有 constructor,这两种类型需要通过其他方式判断。
  2. 函数的 constructor 是不稳定的:自定义对象重写 prototype 后,原有的 constructor 引用会丢失,默认为 Object。
F.prototype = { a: 'XXXX' };
const ff = new F();
ff.constructor === F; // false
ff.constructor;       // ƒ Object() { [native code] }

原因:F.prototype 被重新赋值为 {},{} 是 new Object() 的字面量,会把 Object 原型上的 constructor 传给 {}。

重写原型一般需要给 constructor 重新赋值:ff.constructor = F,避免丢失。

4. Object.prototype.toString.call()

最通用的方法,统一返回 "[object Xxx]"。

Object.prototype.toString.call(1);     // '[object Number]'
Object.prototype.toString.call('1');   // '[object String]'
Object.prototype.toString.call(true);  // '[object Boolean]'
Object.prototype.toString.call(null);  // '[object Null]'
Object.prototype.toString.call([]);    // '[object Array]'
Object.prototype.toString.call({});    // '[object Object]'
Object.prototype.toString.call(new Date()); // '[object Date]'

封装一个通用判断函数:

function getType(obj) {
  const t = typeof obj;
  if (t !== 'object') return t;
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
}

来源整理自:我的有道云笔记