javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS中typeof和instanceof

如何判别JS中的数据类型?一篇文章教你彻底弄懂typeof和instanceof

作者:Jinuss

typeof和instanceof都是JavaScript中用于类型检查的操作符,但它们的工作方式和应用场景有显著不同,这篇文章主要介绍了如何判别JS中的数据类型的相关资料,通过这篇文章可以彻底弄懂typeof和instanceof,需要的朋友可以参考下

引言:JavaScript的类型迷宫

在JavaScript的世界里,数据类型就像变色龙一样善变。有时我们需要准确识别这些"变色龙"的真实身份,这时instanceoftypeof就成了我们的侦探工具。但它们各有所长,也各有局限。今天,我们就来探索这两个侦探的秘密武器,以及它们的替代方案。

第一章:typeof - 快速身份识别器

typeof是JavaScript中最基础的类型检查工具,它能快速告诉我们一个值的基本类型。

console.log(typeof "Hello");      // "string"
console.log(typeof 42);           // "number"
console.log(typeof true);         // "boolean"
console.log(typeof undefined);    // "undefined"
console.log(typeof null);         // "object" (历史遗留问题!)
console.log(typeof []);           // "object"
console.log(typeof {});           // "object"
console.log(typeof function(){}); // "function"

typeof的优势:

typeof的局限:

适用场景:

第二章:instanceof - 家族血统鉴定师

instanceof检查对象是否属于特定构造函数或类的实例,关注的是原型链上的继承关系。

class Animal {}
class Dog extends Animal {}

const fido = new Dog();

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

const arr = [];
console.log(arr instanceof Array);   // true
console.log(arr instanceof Object);  // true

const date = new Date();
console.log(date instanceof Date);   // true

instanceof的优势:

instanceof的局限:

适用场景:

第三章:typeof vs instanceof 实战对决

让我们通过实际场景看看两位侦探的表现:

// 场景1:检查数组
const myArray = [1, 2, 3];

console.log(typeof myArray);      // "object" - 不够具体
console.log(myArray instanceof Array); // true - 完美!

// 场景2:检查数字
const myNumber = 42;

console.log(typeof myNumber);     // "number" - 正确
console.log(myNumber instanceof Number); // false - 失败!

// 场景3:检查null
const myNull = null;

console.log(typeof myNull);       // "object" - 错误!
// console.log(myNull instanceof Object); // 报错!

// 场景4:自定义类
class Pizza {}
const myPizza = new Pizza();

console.log(typeof myPizza);      // "object" - 不够具体
console.log(myPizza instanceof Pizza); // true - 完美!

对决结果

第四章:其他类型侦探工具

1. Array.isArray() - 数组专家

专门解决数组检测问题:

console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false

2. Object.prototype.toString.call() - 万能侦探

最精确的类型检测方法:

console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(42)); // "[object Number]"

3. constructor属性 - 血统追踪器

访问对象的构造函数:

const arr = [];
console.log(arr.constructor === Array); // true

function Car() {}
const myCar = new Car();
console.log(myCar.constructor === Car); // true

注意:constructor属性可以被修改,不够可靠

4. 鸭子类型 - 行为主义者

“如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子”

// 检查是否是类数组对象
function isArrayLike(obj) {
    return obj && 
           typeof obj.length === 'number' && 
           typeof obj[0] !== 'undefined';
}

console.log(isArrayLike([])); // true
console.log(isArrayLike({length: 0})); // true
console.log(isArrayLike("hello")); // true

第五章:现代JavaScript的类型侦探工具

1. 可选链操作符(?.) - 安全访问专家

const user = {
    address: {
        street: "Main St"
    }
};

// 安全访问嵌套属性
console.log(user?.address?.street); // "Main St"
console.log(user?.contacts?.email); // undefined (不会报错)

2. 空值合并运算符(??) - 默认值专家

const name = null;
console.log(name ?? "Anonymous"); // "Anonymous"

const age = 0;
console.log(age ?? 21); // 0 (不会误判0)

3. 类型守卫 - TypeScript的超级侦探

在TypeScript中,我们可以创建自定义类型守卫:

function isFish(pet: Fish | Bird): pet is Fish {
    return (pet as Fish).swim !== undefined;
}

const myPet: Fish | Bird = getPet();

if (isFish(myPet)) {
    myPet.swim(); // TypeScript知道myPet是Fish
} else {
    myPet.fly(); // TypeScript知道myPet是Bird
}

第六章:如何选择合适的侦探工具

  1. 基本类型检查:使用typeof

    • 检查字符串、数字、布尔值等
    • 检查变量是否定义
  2. 对象类型检查

    • 数组:优先使用Array.isArray()
    • 其他内置对象:使用instanceof
    • 自定义对象:使用instanceof
  3. 精确类型识别:使用Object.prototype.toString.call()

  4. 安全访问:使用可选链?.和空值合并??

  5. 类型安全开发:使用TypeScript

第七章:实际应用场景

场景1:表单验证

function validateFormField(value) {
    if (value === null || value === undefined) {
        return "值不能为空";
    }
    
    if (typeof value === "string" && value.trim() === "") {
        return "字符串不能为空";
    }
    
    if (typeof value === "number" && isNaN(value)) {
        return "数字无效";
    }
    
    return "验证通过";
}

场景2:API响应处理

async function fetchUserData() {
    try {
        const response = await fetch("/api/user");
        const data = await response.json();
        
        // 检查是否是期望的数据结构
        if (data && typeof data === "object" && 
            Array.isArray(data.posts) && 
            typeof data.name === "string") {
            return data;
        }
        
        throw new Error("无效的响应格式");
    } catch (error) {
        console.error("获取用户数据失败:", error);
        return null;
    }
}

场景3:多态函数

function calculateArea(shape) {
    if (shape instanceof Rectangle) {
        return shape.width * shape.height;
    }
    
    if (shape instanceof Circle) {
        return Math.PI * shape.radius ** 2;
    }
    
    if (Array.isArray(shape) && shape.length === 2) {
        // 处理 [width, height] 数组
        return shape[0] * shape[1];
    }
    
    throw new Error("不支持的形状类型");
}

结语:成为JavaScript类型侦探大师

在JavaScript的世界里,没有完美的类型检测工具,只有最适合当前场景的选择:

真正的JavaScript侦探大师会根据不同场景灵活选择工具,有时甚至组合使用多种方法。记住,理解这些工具的原理和局限比记住它们的用法更重要。

现在,你已经准备好面对JavaScript类型系统的任何挑战了!出发吧,类型侦探!

到此这篇关于JS中typeof和instanceof的文章就介绍到这了,更多相关JS中typeof和instanceof内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文