JS 数据类型检测的方式

js 的数据类型检查通常有 typeofinstanceofconstructortoString 这四种方法

数据类型

在 JavaScript 中数据类型分为两大类, 基本数据类型引用数据类型

  • 基本数据类型:Undefined、Null、Boolean、Number、String、Symbol(ES6 新增)和 BigInt(ES10 新增);

    Symbol

    在对象中我们可以使用 symbol 函数生成的值当作属性名,因为该属性名是 Symbol 数据类型的,这表示该值是独一无二,避免与其它属性名发生冲突。

js 复制代码
let name = Symbol('name'); 
let obj={ 
    [name]:'小李',
    age: 18,
    job: '法师'
}

console.log(typeof Symbol('name')) // symbol

Symbol 作为键名,并不会被常规的方法遍历得到,例如 for...in、for...of、Object.keys(obj)、Object.values(obj)、Object.getOwnPropertyNames()。

可以遍历得到的,例如 Object.getOwnPropertySymbols()、Reflect.ownKeys()。

BigInt

是一种特殊的数字类型,它支持任意长度的整数,在 JavaScript 中可以表示任意大的整数。

我们可以在整数后面添加 n,或者使用 BigInt() 函数来创建。

js 复制代码
console.log(typeof BigInt('12521111111155')) // bigint
console.log(typeof 1236721111111n) // bigint
  • 引用数据类型:对象(Object)类型,是一组由键、值组成的无序集合;2、数组(Array)类型,是一组按顺序排列的数据的集合;3、函数(Function)类型,是一段具有特定功能的代码块。

typeof

typeof str 通常检测数据的基本类型, 但对引用类型数据判断的话,除function会被识别出来之外,像null、{}、数组都输出为 object。

js 复制代码
typeof null // 'object'
typeof undefined // 'undefined'
typeof 5 // 'number'
typeof '6' // 'string'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof {} // 'object'
typeof [] // 'object'

instanceof

obj instanceof Object 用于检测构造函数的原型属性是否出现在示例对象的原型链上,可以检测某个对象是否属于某个构造函数

js 复制代码
// 定义构建函数
let Person = function() {}
let man = new Person()
man instanceof Person // true
let person = new String('xxx')
person instanceof String // true
let str = 'string'
str instanceof String // false

//关于 instanceof 的实现原理,如下:
//顺着原型链去找,直到找到相同的原型对象,返回true,否则为false
function myInstanceof(left, right) {
    // 这里先用typeof来判断基础数据类型,如果是,直接返回false
    if(typeof left !== 'object' || left === null) return false;
    // getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
    let proto = Object.getPrototypeOf(left);
    while(true) {                  
        if(proto === null) return false;
        if(proto === right.prototype) return true;//找到相同原型对象,返回true
        proto = Object.getPrototypeof(proto);
    }
}

constructor

constructor 属性返回对象的构造函数。

js 复制代码
let a = 1
let b = "123"
let c = true
console.log(a.constructor === Number)//true
console.log(b.constructor === String)//true
console.log(c.constructor === Boolean)//true

// 不会顺着原型链找
let arr = []
console.log(arr.constructor === Array)
console.log(arr.constructor === Object)

//缺点是可以随意更改constructor,例如
let arr = []
Array.prototype.constructor = 'a'  //更改constructor
console.log(arr.constructor === Array)//false

Object.prototype.toString.call

这个方法是最准确的检测数据类型的方法,这里的 toString 并不是转为字符串,而是返回当前实例所属的类信息的字符串。因为每个对象都有 toString 方法。

然后通过 call 将 this 指向要检测的 Object。

js 复制代码
let a = 123
console.log(Object.prototype.toString.call(a))//[object Number]

总结

  • typeof只能检测除null外的基本数据类型,对于数组、对象、正则等都返回为Object

  • instanceof不能检测基本数据类型,检测引用类型时会顺着原型链往上找,只要原型链上有的,都返回true,同时,可以随意更改原型链的指向,导致检测结果不准确

  • constructor可以检测基本数据类型,也能分辨出数组和对象,但是我们可以随意更改constructor的值,导致检测结果不准确

  • Object.prototype.toString.call(value)可以根据返回的信息准确的检测出被测数据的类型

相关推荐
毕设源码-朱学姐3 分钟前
【开题答辩全过程】以 基于web的生鲜农产品信息管理系统为例,包含答辩的问题和答案
前端
Hello.Reader3 分钟前
Flink 2.0 从 flink-conf.yaml 到 config.yaml 的正确打开方式(含迁移与最佳实践)
java·前端·flink
晚霞的不甘5 分钟前
Flutter for OpenHarmony:注入灵魂:购物车的数据驱动与状态管理实战
android·前端·javascript·flutter·前端框架
skywalk816310 分钟前
cbsd的clonos/control-pane web管理页面一直闪烁和网页打开显示500error 的问题解决(500error问题未解决)
服务器·前端·freebsd·cbsd
weixin_4365250713 分钟前
若依多租户版 - modules中创建子模块
java·服务器·前端
好奇的菜鸟15 分钟前
使用 Vite 快速创建 React + TypeScript 项目全记录
前端·react.js·typescript
*小雪16 分钟前
nvm的安装与管理和npm audit的报错解决
前端·npm·node.js
Marshmallowc18 分钟前
React useState 数据不同步?深度解析无限滚动中的“闭包陷阱”与异步更新丢失问题
前端·javascript·react.js·闭包·fiber架构
某柚啊19 分钟前
解决 minimatch 类型报错问题
前端·webpack·npm
前端 贾公子21 分钟前
npm 发包配置双重身份验证
前端·javascript·微信小程序·小程序·github