别再用错!5种JS类型判断方法,从原理到实战一文吃透

JS类型判断方法有5种,各有优劣和适用场景。本文从原理拆解到代码实战,再到扩展技巧(手写instanceof、重写Symbol.hasInstance)

一、typeof

typeof可以正确的判断除null以外的基本类型;除了函数外其他引用类型都会被判断为object

(二)、typeof原理

不同的对象在底层都表示为二进制;在JavaScript中二进制低位1-3存储其类型信息;

000:对象

010:浮点数

100:字符串

110:布尔值

1:整数

但是对于 undefinednull来说,这两个的信息存储有些特殊;

  • null:所有机器码均为0

  • undefined:用 -2^30整数来表示

所以,typeof在判断null的时候就出现了问题,由于null的所有机器码均为0,因此被当成了对象;

二、instanceof

instanceof只能运用于引用类型;它会顺着原型链一直往上找,找到的话返回true, 否则返回false;

JavaScript 复制代码
/**
  自定义instanceof 
*/
function instanceOf(left, right) {
  let proto = left.__proto__
  while(proto){
    if(proto === right.prototype){
       return true
    }
    proto = proto.__proto__
  }  
  return false
}

instanceof可以通过类的静态方法Symbol.hasInstance修改;

扩展 Symbol.hasInstance

Symbol.hasInstance 是一个改变instanceof操作符默认行为的symbol

instanceof的使用:

JavaScript 复制代码
obj instanceof type;
// 判断引用数据的类型,通过原型链一直往上找,找到的话返回true,否则为false

那么js就会执行Symbol.hasInstance方法;它会调用typeSymbol.hasInstance静态方法,将obj作为参数;

JavaScript 复制代码
class Stack {
}
console.log([] instanceof Stack);
// false

[] 数组不是Stack类所创建的实例,所以返回false。

假设要使[] 数组是Stack类所创建的实例,返回true,我们可以重写 Symbol.hasInstance的方法

JavaScript 复制代码
class Stack {
    static [Symbol.hasInstance](obj) {
        return Array.isArray(obj);
    }
}
console.log([] instanceof Stack);
// true

上面例子中,Stack本应该不是数组,但是可以通过重写Symbol.hasInstance修改instanceof的返回值;

三、Object.prototype.toString

JavaScript的每个值的原型上都会有个toString方法;

Object.prototype.toString.callObject.prototype.toString.apply方法是最全面的;

四、constructor

constructor的判断原理跟instanceof类似;不同的是 constructor 既可以判断引用类型,也可以判读基础类型;

constructor属性可以得知某个实例对象,到底是哪一个构造函数产生的;

Tips

  • nullundefined没有constructor
  • 判断数字时使用()、(123).constructor === Number
  • constructor在类继承时会报错,因为Object被覆盖掉了,检测结果不对了;

五、isArray

只实用于数组;Array.isArray()

六、总结

判断方法 核心特点 避坑点/关键说明
typeof 可判断除null外的基本类型;引用类型(除函数)均判为object null的机器码全为0,会被误判为object;undefined用-2^30整数表示
instanceof 仅适用于引用类型,顺着原型链查找匹配,返回布尔值 可通过类的静态方法Symbol.hasInstance修改默认行为
Object.prototype.toString 最全面的判断方法,可通过call/apply调用,适配所有类型 需通过call/apply绑定目标值,直接调用可能被重写
constructor 可判断基础类型和引用类型,能得知实例的构造函数 null/undefined无constructor;类继承时检测结果可能出错
isArray 专用判断数组,精准高效,仅适用于数组类型 无法判断其他类型,仅针对数组场景使用

感谢您抽出宝贵的时间观看本文;本文是JavaScript系列的第 3 篇,后续会持续更新,欢迎关注~

相关推荐
killerbasd5 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌6 小时前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈6 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫6 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝6 小时前
svg图片
前端·css·学习·html·css3
橘子编程6 小时前
JavaScript与TypeScript终极指南
javascript·ubuntu·typescript
王夏奇6 小时前
python中的__all__ 具体用法
java·前端·python
叫我一声阿雷吧7 小时前
JS 入门通关手册(45):浏览器渲染原理与重绘重排(性能优化核心,面试必考
javascript·前端面试·前端性能优化·浏览器渲染·浏览器渲染原理,重排重绘·reflow·repaint
大家的林语冰7 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong237 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习