全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-16 6 分钟 ✍️ juanwangdev

JavaScript instanceof 原理

instanceof 运算符用于检测对象的原型链是否包含某构造函数的 prototype,是判断继承关系的标准方式。

基本用法

JavaScript
// 检测对象是否为某类的实例
const arr = [1, 2, 3];
console.log(arr instanceof Array);   // true
console.log(arr instanceof Object);  // true(Array 继承 Object)

const obj = {};
console.log(obj instanceof Object);  // true
console.log(obj instanceof Array);   // false

function Foo() {}
const instance = new Foo();
console.log(instance instanceof Foo);   // true
console.log(instance instanceof Object); // true

原理实现

JavaScript
// instanceof 检查左边对象的原型链是否包含右边的 prototype
// 实现原理:
function instanceofImpl(obj, constructor) {
    // 右边必须是函数或有 prototype 的对象
    if (typeof constructor !== 'function') {
        throw new TypeError('Right-hand side must be a function');
    }

    // 获取对象原型
    let proto = Object.getPrototypeOf(obj);

    // 遍历原型链
    while (proto !== null) {
        if (proto === constructor.prototype) {
            return true;  // 找到匹配
        }
        proto = Object.getPrototypeOf(proto);  // 继续向上查找
    }

    return false;  // 原型链末端 null,未找到
}

// 测试
console.log(instanceofImpl([], Array));   // true
console.log(instanceofImpl([], Object));  // true
console.log(instanceofImpl({}, Array));   // false

原型链查找过程

JavaScript
function Animal() {}
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

const dog = new Dog();

// instanceof 检查过程:
// dog instanceof Dog:
//   dog.__proto__ === Dog.prototype ? → true

// dog instanceof Animal:
//   dog.__proto__ === Animal.prototype ? → false
//   dog.__proto__.__proto__ === Animal.prototype ? → true

// dog instanceof Object:
//   dog.__proto__ === Object.prototype ? → false
//   dog.__proto__.__proto__ === Object.prototype ? → false
//   dog.__proto__.__proto__.__proto__ === Object.prototype ? → true

console.log(dog instanceof Dog);    // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true

与 typeof 对比

JavaScript
// typeof:返回数据类型(基本类型和 function)
console.log(typeof 'hello');    // 'string'
console.log(typeof 123);        // 'number'
console.log(typeof true);       // 'boolean'
console.log(typeof undefined);  // 'undefined'
console.log(typeof null);       // 'object'(历史 bug)
console.log(typeof []);         // 'object'
console.log(typeof {});         // 'object'
console.log(typeof function(){}); // 'function'

// instanceof:检测对象的具体类
console.log([] instanceof Array);   // true
console.log([] instanceof Object);  // true
console.log({} instanceof Object);  // true

// 组合使用:准确判断数组
const arr = [];
console.log(typeof arr);           // 'object'
console.log(arr instanceof Array); // true
console.log(Array.isArray(arr));   // true(推荐)

边界情况

JavaScript
// null 和 undefined 不能用 instanceof
console.log(null instanceof Object);     // false
console.log(undefined instanceof Object); // false

// 基本类型不是对象
console.log(123 instanceof Number);   // false
console.log('hi' instanceof String);  // false
console.log(true instanceof Boolean); // false

// 但包装对象是
console.log(new Number(123) instanceof Number);  // true
console.log(new String('hi') instanceof String); // true

// Object.create(null) 无原型
const pureObj = Object.create(null);
console.log(pureObj instanceof Object);  // false(原型链无 Object.prototype)

// 跨 iframe/窗口问题
// 不同环境的 Array.prototype 不同
const iframeArray = iframe.contentWindow.Array;
console.log([] instanceof iframeArray);  // false(原型不匹配)
console.log(Array.isArray([]));         // true(跨环境有效)

原型修改的影响

JavaScript
function Foo() {}
const instance = new Foo();

console.log(instance instanceof Foo);  // true

// 修改原型后
Foo.prototype = {};  // 重写原型
console.log(instance instanceof Foo);  // false(原型链断裂)

// 实例的原型指向旧原型
console.log(instance.__proto__ !== Foo.prototype);  // true

// 新实例指向新原型
const newInstance = new Foo();
console.log(newInstance instanceof Foo);  // true

isPrototypeOf 方法

JavaScript
// isPrototypeOf:检查对象是否在另一对象的原型链中
console.log(Array.prototype.isPrototypeOf([]));      // true
console.log(Object.prototype.isPrototypeOf([]));     // true
console.log(Foo.prototype.isPrototypeOf(instance));  // true

// 对比 instanceof
// obj instanceof Constructor 等价于
// Constructor.prototype.isPrototypeOf(obj)

function Foo() {}
const obj = new Foo();
console.log(obj instanceof Foo);                  // true
console.log(Foo.prototype.isPrototypeOf(obj));    // true

// isPrototypeOf 更灵活(不需要构造函数)
const proto = { x: 1 };
const obj = Object.create(proto);
console.log(proto.isPrototypeOf(obj));  // true
console.log(obj instanceof proto);      // TypeError(右边必须是函数)

类型检测最佳实践

JavaScript
// 数组检测:优先使用 Array.isArray
console.log(Array.isArray([]));      // true
console.log(Array.isArray(arguments)); // false

// 函数检测:typeof
console.log(typeof function(){});    // 'function'

// NaN 检测:Number.isNaN
console.log(Number.isNaN(NaN));      // true

// null 检测:严格相等
console.log(value === null);

// 自定义类检测:instanceof
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog);    // true

// 综合类型检测函数
function getType(value) {
    if (value === null) return 'null';
    if (value === undefined) return 'undefined';
    if (Array.isArray(value)) return 'array';
    if (typeof value === 'function') return 'function';
    return typeof value;
}

注意事项

  • instanceof 只适用于对象,基本类型返回 false
  • 右边必须是函数或有 prototype 的对象
  • 原型被修改后可能导致检测结果变化
  • 跨 iframe/窗口环境可能失效,用 Array.isArray 替代
JavaScript
// instanceof 右边必须是函数
class Foo {}
console.log(new Foo() instanceof Foo);  // true

// 错误示例
const proto = {};
console.log({} instanceof proto);  // TypeError

// 正确使用 isPrototypeOf
console.log(proto.isPrototypeOf(Object.create(proto)));  // true

要点总结

  • instanceof 检查对象原型链是否包含构造函数的 prototype
  • 从对象原型开始,沿 __proto__ 遍历直到 null
  • 找到匹配返回 true,遍历结束返回 false
  • 基本类型(非包装对象)instanceof 结果都是 false
  • Constructor.prototype.isPrototypeOf(obj) 等价于 obj instanceof Constructor
  • 数组检测优先使用 Array.isArray,跨环境有效

📝 发现内容有误?点击此处直接编辑

← 上一篇 JavaScript ES6 类与继承
下一篇 → JavaScript 原型式继承
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库