前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS 数据类型的四种检测方法

JS 数据类型的四种检测方法

作者头像
love丁酥酥
发布2020-07-10 10:15:09
1.5K0
发布2020-07-10 10:15:09
举报
文章被收录于专栏:coding for lovecoding for love

简介

我们在代码中经常要对数据类型进行判断,大家熟知的应该是 typeof,那么它有什么不足,有没有其他方法来进行类型检测呢?

1. typeof

JS 的值包括基本类型和引用类型。基本类型值有以下六种:Number、String、Boolean、Undefined、Null 和 Symbol 。引用类型值即保存在内存中的对象 Object。

typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:number、string、boolean、undefined、symbol、object、function 等。

可以看到七种值类型和 tyoeof 能够分辨出的七种数据类型并不是以一一对应的。

// 返回对应的基本类型
console.log(typeof 1); // "number" (对应 Number)
console.log(typeof '1'); // "string" (对应 String)
console.log(typeof true); // "boolean" (对应 Boolean)
console.log(typeof undefined); // "undefined" (对应 Undefined)
console.log(typeof Symbol(1)); // "symbol" (对应 Symbol)
console.log(typeof {}); // "object" (对应 Object)

// 没有基本类型与之对应
console.log(typeof new Function()); // "function"

// 返回的不是对应的基本类型
console.log(typeof null); // "object"

// 无法检测细分对象类型
console.log(typeof [] ); // "object"
console.log(typeof new Date()); // "object
console.log(typeof new RegExp()); // "object

// 可以检测细分对象类型
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(new Date() instanceof Date); // true
function Person(){}
console.log(new Person() instanceof Person); // true

局限性:

  • null 的检测结果不符合我们的认知,因为其并没有返回对应基本类型值的 "null" 而是 “object”
  • 不能区分数组,日期,正则或者其他的具体类型,因为返回的都是原型链顶端的 ”object”

2. instanceof

instanceof 是用来检测一个实例是否属于某个类。

// 可以检测原型链上所有类
console.log([] instanceof Object); // true
console.log(new Date() instanceof Object);// true
function Person(){}
console.log(new Person() instanceof Person); // true

// 基本类型值(number, string, boolean)转成包装类型才能进行检测
console.log(1 instanceof Number); // false
console.log(new Number(1) instanceof Number); // true
console.log('1' instanceof String); // false
console.log(new String('1') instanceof String); // true
console.log(true instanceof Boolean); // false
console.log(new Boolean(true) instanceof Boolean); // true

// 没有包装类型的基本类型值(undefined, null, symbol)无法检测
console.log(undefined instanceof Undefined); // Uncaught ReferenceError: Undefined is not defined
console.log(undefined instanceof Object); // Uncaught ReferenceError: Null is not defined
console.log(null instanceof Null); // false
console.log(null instanceof Object); // false
console.log(Symbol('1') instanceof Symbol); // false
console.log(Symbol('1') instanceof Object); // false

局限性:

  • 只要在当前实例的原型链上,我们用其检测出来的结果都是true
  • 基本类型值检测繁琐,且检测不全(undefined, null, synbol)
  • 原型链是可以手动修改的

3. constructor 构造函数

构造函数原型上有一个 constructor 属性指向构造函数自身的,参见JS入门难点解析12-继承的实现方式与优缺点。那么如果在实例上使用 construtor 时,就会直接使用其构造函数原型的上的该属性,并指向其构造函数。

// 可以检测其构造函数
console.log([].constructor === Array); // true
console.log({}.constructor ===  Object);// true
function Person(){}
console.log(new Person().constructor === Person);// true

// 原型链不会干扰
console.log([].constructor === Object); // false

// 可以检测 Symbol, 因为 Symbol 本身是一个函数(但是不支持 new)
console.log(Symbol('1').constructor === Symbol); // true

局限性:

  • 基本类型值检测繁琐,且检测不全(undefined, null)
  • constructor 是可以手动修改的

4. Object.prototype.toString

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [Class] 。这是一个内部属性,其格式为 object Xxx ,其中 Xxx 就是对象的类型。

对于 Object 对象,直接调用 toString() 就能返回 object Object 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

这里需要注意,其实内置对象比如 Number, Array 等对象上重写了 toString,用来转换为字符串。所以我们使用 Object.prototype.toString 来进行判断。

// 可以检测其构造函数
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call({})); // [object Object]
function Person(){}
console.log(Object.prototype.toString.apply(new Person())); // [object Person]

// 可以检测所有基本类型
console.log(Object.prototype.toString.apply(undefined)); // [object Undefined]
console.log(Object.prototype.toString.apply(null)); // [object Null]
console.log(Object.prototype.toString.apply(Symbol(1))); // [object Symbol]

缺陷:

基本没缺陷,要说有,就是检测 number 等这类有包装类型的,需要检测其包装类型。

小结

综上可知,如果场景简单,要求不严格,随便怎么用都 okay。但是,如果要严格保证获取的准确性和粒度,建议用 Object.prototype.toString。

以上所述都是获取一个值所属的类型,如果要看反过来看一个类型是否是某值的原型,可以使用

isPrototypeOf -- 判断的是原型

Symbol.hasInstance - 可以改写该属性做一些特殊的判断

等来判断

参考

判断JS数据类型的四种方法

JavaScript数据类型检测的四种方式

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 1. typeof
  • 2. instanceof
  • 3. constructor 构造函数
  • 4. Object.prototype.toString
  • 小结
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档