应根据检测目标选择:判断基本类型和函数用typeof,判断引用类型的实例归属用instanceof;二者分工明确,非替代关系,需结合array.isarray()或object.prototype.tostring.call()弥补各自局限。

开发中选 typeof 还是 instanceof,关键看你要判断的是“值的原始类别”还是“对象的构造来源”。两者不是替代关系,而是分工明确。
用 typeof 判断基本类型和函数
它直接读取值的内部类型标签,速度快、无副作用,适合快速筛查。
- 检查变量是否声明:
typeof x === "undefined"比x === undefined更安全 - 区分数字、字符串、布尔、符号、bigint:
typeof 42n→"bigint" - 识别函数:
typeof fn === "function"(这是typeof唯一对引用类型“特事特办”的情况) - 注意
null会返回"object",属于历史 bug,需单独处理
用 instanceof 判断引用类型的实例归属
它沿着对象的 __proto__ 链向上查找,确认该对象是否由指定构造函数“创建”或继承而来。
- 区分数组和普通对象:
[] instanceof Array→true,而typeof []只是"object" - 验证自定义类实例:
new User() instanceof User - 支持原型链继承判断:
new Dog() instanceof Animal可为true(若Dog继承Animal) - 不适用于基本类型:
"abc" instanceof String→false;只有包装对象才成立
它们各自容易出错的地方
忽略这些细节,判断就可能失准。
-
typeof对所有非函数引用类型都返回"object":数组、正则、日期、Map、Set 全部无法区分 -
instanceof在跨 iframe 场景下失效:不同窗口的Array构造函数不共享prototype - 手动重写构造函数的
prototype后,instanceof会返回false - ES6 类的静态方法
[Symbol.hasInstance]可拦截判断逻辑,导致行为意外
更可靠的组合方案
单一运算符不够时,搭配使用能覆盖更多边界情况。
- 判断是否为数组:优先用
Array.isArray()(最标准),其次obj instanceof Array,避免typeof - 判断是否为日期:
obj instanceof Date或Object.prototype.toString.call(obj) === "[object Date]" - 通用类型识别:用
Object.prototype.toString.call(x)获取精确内部标签,如[object RegExp] - 函数检测:仍首选
typeof fn === "function",兼容性最好











