【前端面试小册】JS-第4节:typeof 与 instanceof 的区别与实战

第4节:typeof 与 instanceof 的区别与实战

一、为什么要区分(问题)

在实际开发和面试中,经常需要“准确判断类型”。常见工具是 typeofinstanceof,但它们侧重点不同,各自有局限。

  • 目标:快速、准确地选择合适的类型判断手段。

二、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]

八、面试高频题

  1. typeof null === 'object' 的原因?
  2. 为什么 [] instanceof Objecttrue
  3. 跨 iframe/realm 如何可靠判断数组?
  4. 实现一个 instanceof 的 polyfill。

九、小结

  • typeof:判断基本类型与函数。
  • instanceof:判断引用类型基于原型链归属。
  • Object.prototype.toString.call:最稳健的通用方案;工程中建议封装 getType 工具。
#前端面试#
前端面试小册 文章被收录于专栏

每天3-4节,跟着我50天学完,一起上岸! 靠它,我拿下阿里/百度/滴滴/字节/快手/腾讯/银行等offer 上岸银行,作为面试官使用,跳槽复习使用的小册

全部评论

相关推荐

Webpack是一个模块打包工具,它的主要目的是将应用程序的各个模块打包成一个或多个文件,以便在浏览器中运行。Webpack的工作原理可以简要概括为以下几个步骤:https://www.nowcoder.com/issue/tutorial?zhuanlanId=Mg58Em&uuid=07d53be4cd034a4ab270d500feebcc8d入口点:Webpack将根据配置文件中指定的入口点开始处理打包过程。入口点是应用程序的起始模块,可以是一个或多个文件,Webpack会从这些文件开始构建依赖关系图。构建依赖关系图:Webpack会分析入口点文件及其依赖的模块,通过静态分析确定它们之间的依赖关系。Webpack会递归地查找所有依赖的模块,直到构建出完整的依赖关系图。资源加载与转换:一旦确定了所有的依赖关系,Webpack会根据配置文件中的规则来处理模块。这些规则可以定义如何加载、解析和转换各种资源,例如JavaScript、CSS、图片等。Webpack会使用相应的加载器(loader)和插件(plugins)来处理模块,并且可以根据需要进行编译、压缩、合并等操作。打包输出:在完成资源加载与转换之后,Webpack会将所有的模块打包成一个或多个输出文件。输出文件的数量和命名方式可以通过配置文件进行调整。常见的输出文件类型包括JavaScript文件、CSS文件和图片等。优化与压缩:Webpack还提供了一些优化功能用于减小打包文件的体积和提升加载性能。例如,Webpack可以通过代码分割将应用程序拆分成多个异步加载的模块,从而减少初始加载时间。另外,Webpack还可以对输出文件进行压缩、混淆和缓存等处理,以提高运行效率。这就是Webpack的基本工作原理。它的强大之处在于可以通过插件和配置文件来灵活地定制打包过程,以满足不同项目的需求。
2025.11.01 在牛客打卡368天!
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务