跳到主要内容

类型概览与判定

数据类型如何分类?​

  • 原始值 (primitive): undefined、null、boolean、number、string、symbol、bigint, 值时操作, 无自有属性;
  • 引用值 (reference): object, 包含 Array、Function、Date、RegExp 等, 按引用操作;
  • 存储差异与复制、传参行为见 原始值与引用值;

typeof 能判断出什么?​

检测对象返回值
undefined"undefined"
Boolean"boolean"
string"string"
number"number"
symbol"symbol"
bigint"bigint"
function"function"
object 或 null"object"
typeof null; // "object"; 历史遗留问题
typeof NaN; // "number"; NaN 属于 number 类型
typeof undeclaredVar; // "undefined"; 未声明变量也不报错
  • 局限: 无法细分引用类型, 且把 null 误判为 object;

instanceof 如何判断引用类型?​

  • 机制: 沿 [[Prototype]] 链查找构造函数的 prototype, 详见 原型与原型链;
  • 原始值: 对原始值判断恒为 false;
  • object 判断: 任意引用值 instanceof Object 恒为 true;
person instanceof Object; // true
colors instanceof Array; // true
pattern instanceof RegExp; // true

判断类型的方法各有什么优劣?​

方法优点缺点
typeof简单, 可判断原始类型无法区分引用类型, null 判为 object
instanceof可判断引用类型的继承关系不能判断原始类型, 跨 realm 失效
constructor可检查除 null/undefined 的类型跨 realm 失效, constructor 可被改写
Object.prototype.toString.call可覆盖所有内置类型旧环境兼容性差
const str = "Hello";
typeof str; // "string"
Object.prototype.toString.call(str); // "[object String]"
  • 组合口径: 原始类型用 typeof, 引用类型用 Object.prototype.toString.call, 需要判断继承关系时用 instanceof;

如何判断空对象与空值?​

  • 空对象: Object.keys(obj).length === 0, 或 for...in 加 hasOwnProperty 过滤原型属性, 或 JSON.stringify(obj) === "{}";
  • 空值: 用宽松相等一次判掉 null 与 undefined;
if (value == null) {
// 同时覆盖 null 与 undefined
}