【前端面试小册】JS-第4节:typeof 与 instanceof 的区别与实战
第4节:typeof 与 instanceof 的区别与实战
一、为什么要区分(问题)
在实际开发和面试中,经常需要“准确判断类型”。常见工具是 typeof 与 instanceof,但它们侧重点不同,各自有局限。
- 目标:快速、准确地选择合适的类型判断手段。
二、typeof(原理与示例)
typeof 用于判断基本类型和函数,返回字符串。
console.log(typeof 1); // 'number'
console.log(typeof 'x'); // 'string'
console.log(typeof true); // 'boolean'
console.log(typeof undefined); // 'undefined'
console.log(typeof Symbol()); // 'symbol'
console.log(typeof BigInt(1)); // 'bigint'
console.log(typeof function(){});// 'function'
局限:无法区分引用类型(数组、对象、正则、日期等),并且 null 会被判为 'object'(历史遗留)。
console.log(typeof {}); // 'object'
console.log(typeof []); // 'object'
console.log(typeof /x/); // 'object'
console.log(typeof null); // 'object' // 易错点
原理简述:底层以若干位标识类型;null 的 bit 模式与对象同源,导致历史遗留返回 'object'。
三、instanceof(原理与示例)
instanceof 用于判断某对象的原型链上是否出现过构造函数的 prototype。
function Person() {}
function Child() {}
Child.prototype = new Person();
const c = new Child();
console.log(c instanceof Child); // true
console.log(c instanceof Person); // true
console.log([] instanceof Array); // true
console.log([] instanceof Object);// true
局限:
- 基本类型字面量判断有误(如
'x' instanceof String // false)。 - 跨 iframe/realm 失效(不同全局对象拥有不同的内建构造函数)。
四、自实现 myInstanceof(示例)
function myInstanceof(left, right) {
if (left == null || (typeof left !== 'object' && typeof left !== 'function')) return false;
if (typeof right !== 'function') throw new TypeError('Right-hand side must be a function');
let proto = Object.getPrototypeOf(left);
const prototype = right.prototype;
while (proto) {
if (proto === prototype) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}
五、三种方案对比(表格)
| 方案 | 适用范围 | 优点 | 局限 | 典型用法 |
|---|---|---|---|---|
| typeof | 基本类型、函数 | 简单、快速 | 无法区分 Array/Object,null 为 object |
判断 primitive、函数 |
| instanceof | 引用类型 | 能基于原型链区分类型 | 基本类型无效、跨 iframe 失效 | 判断自定义类、内建对象实例 |
| Object.prototype.toString.call | 全类型 | 精确、稳定 | 语法冗长 | 通用型、库内实现 |
const getType = (v) => Object.prototype.toString.call(v).match(/\s+(\w+)/)[1];
六、实战建议(最佳实践)
- 判断数组:
Array.isArray(value)(内部也等价于toString判定)。 - 判断纯对象:
value !== null && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype。 - 判断类实例:优先
instanceof;跨上下文(iframe)场景退回toString或特征检测。 - 判断
null:直接value === null。 - 判断 NaN:
Number.isNaN(value)。
七、流程图(如何选择)
flowchart TD
A[需要判断类型] --> B{是否为 null/undefined}
B -- 是 --> C[直接比较 value === null/undefined]
B -- 否 --> D{是否判断数组}
D -- 是 --> E[Array.isArray]
D -- 否 --> F{是否判断类实例}
F -- 是 --> G[instanceof]
F -- 否 --> H{是否判断基本类型}
H -- 是 --> I[typeof]
H -- 否 --> J[Object.prototype.toString.call]
八、面试高频题
typeof null === 'object'的原因?- 为什么
[] instanceof Object为true? - 跨 iframe/realm 如何可靠判断数组?
- 实现一个
instanceof的 polyfill。
九、小结
typeof:判断基本类型与函数。instanceof:判断引用类型基于原型链归属。Object.prototype.toString.call:最稳健的通用方案;工程中建议封装getType工具。
前端面试小册 文章被收录于专栏
每天3-4节,跟着我50天学完,一起上岸! 靠它,我拿下阿里/百度/滴滴/字节/快手/腾讯/银行等offer 上岸银行,作为面试官使用,跳槽复习使用的小册