类型检测需按问题选择工具:问原始值用typeof,问构造器用instanceof;typeof快但无法区分对象类型,instanceof可判实例但跨环境失效;实际应优先用Array.isArray()或Object.prototype.toString.call()。

JavaScript 类型检测不是选一个“对的”运算符就完事,而是根据你要回答的问题来选:是问“它是什么原始值?”,还是问“它是不是某个类造出来的?”。typeof 和 instanceof 根本不是同一类工具,硬比谁“更好”容易踩坑。
什么时候用 typeof:判断基本类型或变量是否存在
typeof 本质是读取 JS 引擎给值打的“类型标签”,所以快、轻量、安全(不会报错),但只认原始类型和 function;对所有对象(包括数组、日期、正则、null)一律返回 "object" —— 这不是 bug,是设计如此。
- ✅ 适合场景:
if (typeof cb === "function") { cb() }、检查变量是否声明:typeof window !== "undefined" - ⚠️ 注意陷阱:
typeof null返回"object",typeof []和typeof {}都是"object",无法区分 - ❌ 别指望它识别
Date、Array、RegExp等具体构造器类型
什么时候用 instanceof:确认对象由哪个构造函数创建
instanceof 不看类型标签,而是顺着对象的 __proto__ 链往上找,看能不能碰到右操作数的 .prototype。它回答的是“这个对象是不是 new X() 出来的?”而不是“它是什么类型?”
- ✅ 适合场景:判断自定义类实例、
arr instanceof Array(在单窗口下可靠)、date instanceof Date - ⚠️ 注意陷阱:跨 iframe 或不同全局环境时失效(比如
iframe.contentWindow.Array和主页面的Array是两个构造器) - ❌ 对原始值无效:
"abc" instanceof String永远是false(字符串字面量不是String实例)
为什么不能只靠它们?常见组合方案
单独用 typeof 或 instanceof 都会漏判。实际项目中常组合使用,或换更稳的方案:
立即学习“Java免费学习笔记(深入)”;
- 判断数组:优先用
Array.isArray()(ES5+,跨 frame 安全),比arr instanceof Array更可靠 - 判断日期/正则/错误等内置对象:用
Object.prototype.toString.call(value),例如:Object.prototype.toString.call(new Date()) // "[object Date]"
- 需要兼容老环境且要区分对象类型时,可封装一层:
function getType(obj) { return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); }
最易被忽略的一点:类型检测从来不是为了“分类而分类”,而是服务于后续逻辑分支。别在 if 条件里堆砌 typeof x === "object" && x !== null && x.constructor === Array 这种脆弱判断——直接用 Array.isArray(x) 或 value instanceof Map(明确知道运行环境)更干净。类型检测的终点,是让代码不崩溃、不误判、不依赖隐式转换。











