`typeof` 和 `instanceof` 的核心实现原理

1. typeof 的核心实现原理

JavaScript 内部的类型标签机制

在 JavaScript 引擎内部,每个值都有一个类型标签(type tag)存储在值的低位数位中。

// 模拟 typeof 的底层实现逻辑
function myTypeof(value) {
    // 1. 处理 null 的特殊情况
    if (value === null) {
        return 'object';
    }
    
    // 2. 处理函数的特殊情况
    if (typeof value === 'function') {
        return 'function';
    }
    
    // 3. 基于值的内部 [[Class]] 属性判断
    const type = Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
    
    // 4. 特殊处理:document.all 在旧浏览器中返回 'undefined'
    if (value === undefined) {
        return 'undefined';
    }
    
    // 5. 基本类型映射
    const typeMap = {
        number: 'number',
        string: 'string',
        boolean: 'boolean',
        symbol: 'symbol',
        bigint: 'bigint',
        object: 'object'
    };
    
    return typeMap[type] || 'object';
}

实际引擎中的实现(简化版)

// V8 引擎中的简化实现逻辑
function V8Typeof(obj) {
    // 检查值的内部表示
    const type = %_ClassOf(obj);
    
    switch (type) {
        case 'Number': return 'number';
        case 'String': return 'string';
        case 'Boolean': return 'boolean';
        case 'Symbol': return 'symbol';
        case 'BigInt': return 'bigint';
        case 'Function': return 'function';
        case 'Undefined': return 'undefined';
        case 'Null': return 'object'; // 历史遗留问题
        default: return 'object';
    }
}

typeof 的特殊行为解释

// 历史遗留的 bug
typeof null === 'object' // true

// 函数特殊处理
typeof function() {} === 'function' // true
typeof class {} === 'function'      // true

// 其他对象
typeof [] === 'object'              // true
typeof {} === 'object'              // true
typeof new Date() === 'object'      // true

2. instanceof 的核心实现原理

instanceof 的底层实现

// instanceof 的 polyfill 实现
function myInstanceof(instance, constructor) {
    // 1. 基本类型直接返回 false
    if (instance === null || typeof instance !== 'object' && typeof instance !== 'function') {
        return false;
    }
    
    // 2. 获取实例的原型
    let proto = Object.getPrototypeOf(instance);
    
    // 3. 沿着原型链向上查找
    while (proto !== null) {
        // 4. 如果找到构造函数的 prototype,返回 true
        if (proto === constructor.prototype) {
            return true;
        }
        // 5. 继续向上查找
        proto = Object.getPrototypeOf(proto);
    }
    
    // 6. 原型链尽头未找到,返回 false
    return false;
}

更完整的实现(包含边界情况)

function completeInstanceof(instance, constructor) {
    // 检查 constructor 是否有效
    if (typeof constructor !== 'function') {
        throw new TypeError('Right-hand side of instanceof is not callable');
    }
    
    // 检查 instance 是否为对象(除 null 外)
    if (instance === null || (typeof instance !== 'object' && typeof instance !== 'function')) {
        return false;
    }
    
    // 获取构造函数的原型
    const constructorProto = constructor.prototype;
    
    // 如果构造函数的原型不是对象,抛出错误
    if (typeof constructorProto !== 'object' && constructorProto !== null) {
        throw new TypeError('Function has non-object prototype in instanceof check');
    }
    
    // 遍历原型链
    let currentProto = Object.getPrototypeOf(instance);
    while (currentProto !== null) {
        if (currentProto === constructorProto) {
            return true;
        }
        currentProto = Object.getPrototypeOf(currentProto);
    }
    
    return false;
}

3. 实际应用示例

typeof 应用场景

function typeCheck(value) {
    const type = typeof value;
    
    switch (type) {
        case 'string':
            return `字符串: ${value}`;
        case 'number':
            return `数字: ${value}`;
        case 'boolean':
            return `布尔值: ${value}`;
        case 'undefined':
            return '未定义';
        case 'function':
            return '函数';
        default:
            if (value === null) return 'null';
            return `对象: ${value.constructor.name}`;
    }
}

console.log(typeCheck('hello'));    // 字符串: hello
console.log(typeCheck(42));         // 数字: 42
console.log(typeCheck(null));       // null

instanceof 应用场景

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

const dog = new Dog();
const cat = new Cat();

console.log(myInstanceof(dog, Dog));     // true
console.log(myInstanceof(dog, Animal));  // true
console.log(myInstanceof(dog, Cat));     // false
console.log(myInstanceof([], Array));    // true
console.log(myInstanceof([], Object));   // true

4. 性能优化版本

优化的 instanceof(使用缓存)

function optimizedInstanceof() {
    const cache = new WeakMap();
    
    return function(instance, constructor) {
        // 基本类型快速返回
        if (instance === null || typeof instance !== 'object') {
            return false;
        }
        
        // 检查缓存
        const key = `${constructor.name}-${typeof instance}`;
        if (cache.has(key)) {
            return cache.get(key);
        }
        
        // 原型链查找
        let proto = Object.getPrototypeOf(instance);
        while (proto !== null) {
            if (proto === constructor.prototype) {
                cache.set(key, true);
                return true;
            }
            proto = Object.getPrototypeOf(proto);
        }
        
        cache.set(key, false);
        return false;
    };
}

const fastInstanceof = optimizedInstanceof();

5. 核心区别总结

特性 typeof instanceof
检查目标 值的类型 原型链关系
返回值 字符串 布尔值
处理null 返回'object' 返回false
性能 O(1) O(n) - 原型链长度
适用场景 基本类型检查 继承关系检查

实际使用建议

// typeof 适合检查基本类型
if (typeof variable === 'string') {
    // 处理字符串
}

// instanceof 适合检查对象类型和继承关系
if (variable instanceof Error) {
    // 处理错误对象
}

// 对于数组,推荐使用 Array.isArray
if (Array.isArray(variable)) {
    // 处理数组
}
posted @ 2025-11-18 11:51  阿木隆1237  阅读(10)  评论(0)    收藏  举报