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

JavaScript的数据类型

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

原始类型(Primitive Types)

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

  • Undefined:表示变量未定义。

  • Null:表示空值。

  • Boolean:表示布尔值,只有两个取值:true 和 false

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

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

  • String:表示字符串。

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

引用类型(Reference Types)

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

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

整理了一份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】即可免费获取

类型判断

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

typeof

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

image.png

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

在JavaScript的早期版本中,只有五种数据类型: UndefinedNullBooleanNumber 和 String。对象类型是后来加入的,包括 Object 和 Function。 当时,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 对原始类型总是返回 false。 

image.png

手写myinstanceof

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

 

js

复制代码

方法一:递归思路 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也可以吗? 是的 他也可以?

我们先来看看官方文档:

image.png

 用我们强大的外语知识储备翻译就是这样的

 

lua

复制代码

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指向我们要判断的类型。 

image.png

 同时呢,我们可以实现一个通用类型判断函数

 

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

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

  • 26
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值