likes
comments
collection
share

JS类型判断——聊聊你心里的顶美

作者站长头像
站长
· 阅读数 24

JavaScript的数据类型

在JavaScript中,数据类型分为两大类:原始类型(Primitive Types)引用类型(Reference Types)

原始类型(Primitive Types)

原始类型是最基本的数据类型,它们直接包含值。JavaScript有七种原始类型:

  • Undefined:表示变量未定义。

  • Null:表示空值。

  • Boolean:表示布尔值,只有两个取值:truefalse

  • Number:表示数字,包括整数和浮点数。

  • BigInt:表示任意精度的整数。

  • String:表示字符串。

  • Symbol:表示唯一且不可变的标识符。

引用类型(Reference Types)

引用类型是对象类型,它们存储的是对值的引用,而不是值本身。

  • Object JavaScript中最基本的引用类型,用于存储键值对。
  • Array 表示有序集合,可以存储不同类型的值。
  • Function JavaScript中函数也是对象,可以通过函数表达式或函数声明创建。
  • RegExp 表示正则表达式,用于模式匹配。
  • Date 用于处理日期和时间。
  • 其他内置对象 包括 Map, Set, WeakMap, WeakSet, ArrayBuffer, SharedArrayBuffer, DataView, Promise 等。

类型判断

在一些项目场景中,我们需要用到类型判断,比如输入验证、多态处理等。在刚开始接触编程,我们用的最多的可能就是typeof了,但是,也还有其他方法适用于不同的场景。

typeof

如果我们试过,我们就会知道其实typeof有一些弊端

JS类型判断——聊聊你心里的顶美

无法判断除function之外的引用类型

在JavaScript的早期版本中,只有五种数据类型: UndefinedNullBooleanNumberString。对象类型是后来加入的,包括 ObjectFunction。 当时,JavaScript 的 typeof 操作符被设计为简单地返回这些基础类型的字符串表示。而对象类型的所有实例都被归类为 object。这是因为在那时,对象类型还没有细分。

函数虽然也是对象的一种,但它们在JavaScript中具有非常特殊的地位和作用。函数不仅仅是数据容器,它们还具有可调用的特性,可以执行代码。因此,JavaScript设计者决定让 typeof 操作符对函数返回 'function',以便更明确地区分函数和其他对象。

可以判断除null之外的原始类型

为何null也是object呢?这其实是一个历史遗留问题,在JavaScript的最初版本中,使用的是32位系统,null 被表示为一个空的引用对象(即所有位都为0的对象指针),而typeof的判断原理是:将值转换为二进制后看其前三位是不是0 ,因此被错误地检测为对象类型。

instanceof()

instanceof 是JavaScript中的一个操作符,用于判断一个对象是否是另一个对象的实例。它在面向对象编程中非常有用,可以用来检查对象的类型,尤其是在继承关系中。

instanceof 如何判定的呢?

请大家思考一下,既然instanceof是用于判断一个对象是否是另一个对象的实例,那么,他是否是沿着原型链来判定的呢?

其实是的,instanceof的判定会沿着对象的原型链向上搜索,直到找到与构造函数的 prototype 属性严格相等的对象。如果找到,则返回 true,否则返回 false

那么有人就会问了,原始类型不是有包装类吗?

只能判断引用类型

当我们访问一个原始类型的属性或调用一个方法时,JavaScript 会在后台创建一个临时的包装对象,允许我们像对象一样操作这些原始值。但是,这些包装对象是短暂的,并且在操作完成后会被销毁。instanceof 操作符检查的是对象的原型链,而不是值本身。当我们使用 instanceof 时,它检查的是对象的构造函数,而原始类型没有构造函数,所以 instanceof 对原始类型总是返回 falseJS类型判断——聊聊你心里的顶美

手写myinstanceof

既然是沿着原型链,那我们是否可以来自己试试

方法一:递归思路
function myinstanceof(L, R) {
    // 如果 L 是 null 或 undefined,直接返回 false
    if (L == null) return false;
    
    // 获取 L 的原型对象
    let proto = Object.getPrototypeOf(L);
    
    // 递归地检查原型链
    if (proto === R.prototype) {
        return true;
    } else if (proto === null) {
        return false;
    } else {
        return myinstanceof(proto, R);
    }
}

方法二:while
function myinstanceof(L, R) {
    // 如果 L 是 null 或 undefined,直接返回 false
    if (L == null) return false;
    
    // 获取 L 的原型对象
    let proto = Object.getPrototypeOf(L);
    
    // 递归地检查原型链
    while (proto !== null) {
        if (proto === R.prototype) {
            return true;
        }
        proto = Object.getPrototypeOf(proto);
    }
    
    return false;
}

object.prototype.toString()

我想你没有想到吧,toString也可以吗? 是的 他也可以?

我们先来看看官方文档:

JS类型判断——聊聊你心里的顶美 用我们强大的外语知识储备翻译就是这样的

    1.如果toString接收的值是undefined,则返回"[object Undefined]"
    2.如果toString接收的值是null,则返回"[object Null]"
    3.调用 ToObject(x)  将x转为对象(这是内置方法) 
      此时得到的对象内部一定拥有一个属性[[class]],而该属性[[class]]的值就是x的类型
    4.设 class是[[class]]的值 
    5.返回由"[object"和class 和"]" 拼接得到的字符串

如此可见,toString方法也可以的,但这是对象的一个,和其他类型的不同

  • 数组的toString() 将数组中的元素用逗号的方式拼接成字符串
  • 其他的toString() 直接将值修改成字符串字面量

Object.prototype.toString 内部是通过 this 绑定来决定返回的类型字符串。当调用 Object.prototype.toString.call(value) 时,value 被传入并绑定为 this,然后返回该值的内部 [[Class]] 属性表示的类型。每种类型的对象都有其内部的 [[Class]] 属性,这个属性决定了 Object.prototype.toString 返回的结果。

是的 我们可以用call方法来把this指向我们要判断的类型。 JS类型判断——聊聊你心里的顶美 同时呢,我们可以实现一个通用类型判断函数

function getType(value) {
    return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(getType("hello")); // String
console.log(getType(42)); // Number
console.log(getType(true)); // Boolean
console.log(getType(undefined)); // Undefined
console.log(getType(null)); // Null
console.log(getType(Symbol())); // Symbol
console.log(getType(10n)); // BigInt
console.log(getType([])); // Array
console.log(getType({})); // Object
console.log(getType(function(){})); // Function
console.log(getType(/regex/)); // RegExp
console.log(getType(new Date())); // Date
console.log(getType(new Map())); // Map
console.log(getType(new Set())); // Set
console.log(getType(new WeakMap())); // WeakMap
console.log(getType(new WeakSet())); // WeakSet
console.log(getType(new Error())); // Error
console.log(getType(new CustomType())); // Object

有没有和我一样,找到真爱了,哈哈哈

转载自:https://juejin.cn/post/7381663975917207563
评论
请登录