当前位置: 首页 > news >正文

js判断数据类型的几种方法及其局限性(typeof, instanceof, Object.prototype.toString.call())


js中判断了类型的方法有很多, 这篇文章主要来说一下常用的几种判断类型的方法,以及使用:

每个方法都各有优缺点,在日常使用的时候请结合这些优缺点进行斟酌:

1. 使用typeof判断数据类型

javaScript中typeof可以判断以下类型:

  1. undefined: 未定义的变量或者值

  2. boolean: 布尔类型, true 或false

  3. number: 数值类型, 包括整数,浮点数, NaN, 和Infinity (无穷大)

  4. string: 字符串类星星, 表示文本

  5. symbol:符号类型,ES6中新增的基本数据类型

  6. function: 函数类型,可以作为一种特殊的对象类型

以下未测试代码以及输出内容:

let num = 213
console.log('type num=', typeof num) // numberlet str = '123'
console.log('type str=', typeof str) //stringlet nullValue = null
console.log('type nullValue=', typeof nullValue) // objectlet undefinedValue = undefined
console.log('type undefinedValue=', typeof undefinedValue)// undefinedlet obj = {name:'卡卡西',age:12}
console.log('type obj=', typeof obj) // objectlet boolValue = true
console.log('type boolValue=', typeof boolValue) //booleanlet symbolValue = Symbol('kk')
console.log('type symbolValue=', typeof symbolValue) //symbolfunction fun() {}
console.log('type fun=', typeof fun) //functionlet arr = [1,2,3]
console.log(typeof arr) // object

需要注意的是null和arr这些也是typeof判断类型的局限性所在;

typeof判断类型的局限性:

  1. typeof null的结果是object: 这是一个历史遗留问题, 在JavaScript最初的实现中将null的类型判断错误地设为object,因此使用typeof操作符判断null的时候得到的结果是object而不是null
  2. typeof数组|对象 返回的结果也是object: 虽然数组和对象在JavaScript中分别属于两种不同的数据类型,但是使用typeof判断他们的结果都是’object’ 无法区分他们的具体类型
  3. 不能判断自定义对象类型:使用typeof操作符无法自定义对象的具体类型,因为所有的自定义对象都被视为一种object类型

需要注意的是,typeof能够快速判断出一些简单的类型的数据,但是对于复杂的数据类型判断会有一定的局限性,因此在实际编写代码时,需要结合其他的方法和技巧来判断数据类型

2. 使用instanceof判断类型

instanceof是javaScript中的一种运算符,用于判断某个对象是否属于某个类(或其父类)的实例,语法如下

object instance of constructor

测试代码如下:


function Person(name) {this.name = name;
}let person1 = new Person('卡卡西')console.log(person1 instanceof Person) // trueconsole.log('Person',Person) //[Function: Person]console.log('person1',person1) //Person { name: '卡卡西' }console.log('Person()',Person()) //undefinedclass A {}
class B extends A {}let b = new B()
console.log(b instanceof B) // true
console.log(b instanceof A) //trueclass Animal {}
const dog = {};
dog.constructor = Animal;
console.log(dog instanceof Animal); // false

虽然instanceof运算符可以用来判断是否属于某个类的实例,但是他也存在一些局限性:

  1. 无法判断基本数据类型: instanceof 只能判断对象是否属于某个类的实例,不能判断基本数据类型,比如字符串,数字,如果要判断基本数据类型,需要使用其他方法
  2. construct 属性可能被篡改: instanceof 的判断依赖于对象的construct属性,如果对象的constructor属性被修改或篡改,那么instanceof就无法正确判断对象所属的类
  3. 原型链较深时效率较低:instanceof 的判断是基于原型链的,当原型链较深时,instanceof 的效率会较低,因为它需要遍历整个原型链才能找到判断条件中的构造函数。
    综上所述,虽然 instanceof 运算符在某些情况下可以很方便地判断对象所属的类,但是在实际开发中需要注意其局限性,并结合其他方法和技巧来进行类型判断。

3. 使用Object.toString.call()判断数据类型

使用Object.toString.call()可以用来判断:

  1. 判断基本数据类型
  2. 判断复杂数据类型
  3. 判断null和undefined

需要注意的是,Object.prototype.toString 方法返回的字符串格式为 “[object 数据类型]”,其中数据类型和 JavaScript 中的数据类型名称一致。此外,由于该方法是 Object 类型的原型方法,因此需要通过 call 方法来调用,确保 this 指向正确。

const num2 = 0;
console.log('object.toString.call(num2)',Object.prototype.toString.call(num2))//[object Number]const str1 = '卡卡西'
console.log('object.toString.call(str1)',Object.prototype.toString.call(str1))// [object String]const obj2 = {name:'佐助',age:'23'}
console.log('object.toString.call(obj2)',Object.prototype.toString.call(obj2))//[object Object]const arr2 = [1,2,3,4];
console.log('object.toString.call(arr2)',Object.prototype.toString.call(arr2))//[object Array]const nullValue2 = null
console.log('object.toString.call(nullValue2)',Object.prototype.toString.call(nullValue2))//[object Null]class Student {name;constructor(name) {this.name = name;}}const student1 = new Student('周周');
console.log('object.toString.call(student1)',Object.prototype.toString.call(student1))// [object Object]class Student2 {name;constructor(name) {this.name = name;}toString(){console.log(this.name)}// 重写 Symbol.toStringTag 属性get [Symbol.toStringTag]() {return 'Student2';}
}const student2 = new Student2('周周')
console.log('object.toString.call(student2)',Object.prototype.toString.call(student2))// [object Student2]

Object.prototype.toString.call()方法判断类型的局限性:

  1. 无法准确判断自定义类型: Object.prototype.toString.call 方法虽然可以准确地判断内置对象(例如 Array、Object、Function 等)和基本数据类型,但无法准确地判断开发者自定义的类。如果想让他能判断自定义类型需要重写Symbol.toStringTag 属性
  2. 不能区分继承关系: Object.prototype.toString.call 方法只能根据对象的原型链进行判断,无法区分不同构造函数创建的相似对象的继承关系,
    4.不能跨域判断:由于 JavaScript 中的安全机制,当脚本执行跨域操作时,Object.prototype.toString.call 方法也可能会返回错误的结果。这是因为部分浏览器实现了“沙箱”机制,阻止了跨域脚本访问其他域名下的对象。
http://www.lryc.cn/news/92917.html

相关文章:

  • 【MySQL】一文带你掌握聚合查询和联合查询
  • 初步了解JVM
  • 嘀嗒陪诊小程序v1.0.8+小程序前端
  • Java中线程的生命周期
  • 光线追踪RayTracing,基本原理,判断物体与光线相交
  • 三十六、数学知识——组合数(递推法 + 预处理法 + 卢卡斯定理 + 分解质因数求解组合数 + 卡特兰数)
  • LinuxC编程——高级文件操作
  • 【基础知识整理】图的基本概念 邻接矩阵 邻接表
  • 5.程序控制结构|Java学习笔记
  • 【最优PID 整定】PID性能指标(ISE,IAE,ITSE和ITAE)优化、稳定性裕量(Matlab代码实现)
  • Linux内核中断和Linux内核定时器
  • OMG--IDL(Interface Definition Language)
  • 英语学习:M开头
  • 【计算机组成原理与体系结构】控制器
  • 结构化命令
  • Java Web实训项目:西蒙购物网
  • ChatGPT Prompt 提示词设计技巧必知必会
  • 尚硅谷-云尚办公-项目复盘
  • nacos升级到2.0.3(单机模式)
  • Koa学习3:用户添加、错误处理
  • 网络安全入门学习第十五课——PHP基础
  • 电子科技大学 数学专业-功不唐捐,玉汝于成
  • Android10.0 iptables用IOemNetd实现删除子链功能的实现
  • OpenGL光照之光照贴图
  • 2018~2019 学年第二学期《信息安全》考试试题(B 卷)
  • LeetCode-C#-0002.两数相加
  • 访问修饰符private,default,protected,public访问等级区别
  • 阿里云(Linux)安装Docker教程
  • Linux C编程基础:获取时间
  • Spring核心注解