JS数据类型判断的几种常用方法


Posted in Javascript onJuly 07, 2020

JavaScript 中常见数据类型有Number、String、Boolean、Object、Array、Json、Function、Date、RegExp、Error、undefined、Null等十几种。ES6还有新增的数据类型有Symbol、Set、Map等。在实际应用中,我们经常需要判断数据类型,现在我归纳几种方法,希望对大家有所帮助。

typeof 判断(最常用)

typeof 是 JS 提供的一个运算符,专门用来检测一个变量的类型 。 typeof 有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算。

function doSomething() {
  console.log('Hello World!');
}
console.log(typeof 1); // number
console.log(typeof 'Hello'); // string
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof doSomething); // function
console.log(typeof true); // boolean
console.log(typeof new Date()); // object
console.log(typeof new RegExp()); // object
console.log(typeof JSON.stringify({
  name: 'zhencanhua'
})); // string
console.log(typeof null); // object
console.log(typeof undefined); // undefined
console.log(typeof (new Error('error!'))); // object

console.log(typeof a); // undefined
console.log(typeof Symbol()); // symbol
console.log(typeof new Set()); // object
console.log(typeof new Map()); // object

从上面打印结果可以看出,typeof 不能区分引用型数据的类型和 null。另我们可以使用 Array.isArray(arr) 将数组类型的数据从中筛选出来。

instanceof 判断(了解)

instanceof 用来检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。 语法:object(实例对象) instanceof constructor(构造函数)。是的话返回 true,否则返回 false。所以, instanceof 运算符只能用作对象的判断。 针对 typeof 不能判断的引用型数据,我们可以使用 instanceof 运算符。

let arr1 = [1, 2, 3];
let obj1 = {
  name: '小明'
};
function Persion() { }
let persion1 = new Persion();
console.log(arr1 instanceof Array); // true
console.log(arr1 instanceof Object); // true,Array 是Object的子类
console.log(obj1 instanceof Object); // true
console.log(obj1 instanceof Array); // false
console.log(Persion instanceof Function, Persion instanceof Object); // true true
console.log(null instanceof Object); // false
console.log(persion1 instanceof Persion, persion1 instanceof Function, persion1 instanceof Object); // true false true
// String对象和Date对象都属于Object类型
let str1 = 'Hello';
let str2 = new String();
let str3 = new String('你好');
let myDate = new Date();
console.log(str1 instanceof String, str1 instanceof Object); // false, false
console.log(str2 instanceof String, str2 instanceof Object); // true, true
console.log(str3 instanceof String, str3 instanceof Object); // true, true
console.log(myDate instanceof Date, myDate instanceof Object); // true, true

从上面的判断可以看出,instanceof 的使用限制很多,而且还不能很清晰方便的判断出一个实例是数组还是对象或方法。

针对上面方法的弊端,我们可以使用 Object.prototype上的原生toString()方法来检测数据的类型。

Object.prototype.toString.call() 判断(最靠谱)

Object 是 JS 提供的原生对象, Object.prototype.toString对任何变量都会返回这样一个字符串"[object class]",class 就是 JS 内置对象的构造函数的名字。 call是用来改变调用函数作用域的。

Object.prototype.toString() 在toString方法被调用时执行下面的操作步骤:

  1. 获取this对象的[[Class]]属性的值。(所以使用call来改变this的指向)
  2. 将字符串"[object ",第一步获取的值, 以及 "]"拼接成新的字符串并返回。

[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性。在规范中,[[Class]]是这么定义的: 内部属性的描述, [[Class]] 是一个字符串值,表明了该对象的类型。

读了上面的说明,用 call 的关键地方就在第1步,获取的是 this 对象,不加 call 改变作用域时 this 指向的是Object.prototype。

function doSomething() {
  console.log('Hello World!');
}
// 使用Object.prototype.toString.call来判断
console.log(Object.prototype.toString.call(1)); // [object Number]
console.log(Object.prototype.toString.call('Hello')); // [object String]
console.log(Object.prototype.toString.call(false)); // [object Boolean]
console.log(Object.prototype.toString.call({})); // [object Object]
console.log(Object.prototype.toString.call([1, 2, 3])); // [object Array]
console.log(Object.prototype.toString.call(new Error('error!'))); // [object Error]
console.log(Object.prototype.toString.call(new Date())); // [object Date]
console.log(Object.prototype.toString.call(new RegExp())); // [object RegExp]
console.log(Object.prototype.toString.call(doSomething)); // [object Function]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(JSON.stringify({
  name: 'zhencanhau'
}))); // [object String]
console.log(Object.prototype.toString.call(Math)); // [object Math]
console.log(Object.prototype.toString.call(Symbol('abc'))); // [object Symbol]
console.log(Object.prototype.toString.call(new Set())); // [object Set]
console.log(Object.prototype.toString.call(new Map())); // [object Map]

但在实际应用时我们只想获取返回的结果中数组的第二项,比如"[object Number]",我们只想要Number这段字符,那么我们可以写个函数进行过滤:

// 通过定义一个公共函数获取数据类型
function getTypeName(val) {
  let str = Object.prototype.toString.call(val);
  return /^\[object (.*)\]$/.exec(str)[1];
}
console.log(getTypeName(false)); // Boolean
console.log(getTypeName()); // Undefined
console.log(getTypeName(null)); // Null

上面的问题完美解决。

constructor 判断(比较常用)

每一个对象实例都可以通过 constrcutor 对象来访问它的构造函数 。JS 中内置了一些构造函数:Object、Array、Function、Date、RegExp、String等。我们可以通过数据的 constrcutor 是否与其构造函数相等来判断数据的类型。

var arr = [];
var obj = {};
var date = new Date();
var num = 110;
var str = 'Hello';
var getName = function(){};
var sym = Symbol();
var set = new Set();
var map = new Map();

arr.constructor === Array; // true
obj.constructor === Object; // true
date.constructor === Date; // true
str.constructor === String; // true
getName.constructor === Function; // true
sym.constructor === Symbol; // true
set.constructor === Set; // true
map.constructor === Map // true

但是这种方式仍然有个弊端,就是 constructor 所指向的的构造函数是可以被修改的。

function Name(name) {
  this.name = name;
}

function Stuent(age) {
  this.age = age;
}
// 将构造函数Name的实例赋给Student的原型,Student的原型的构造函数会发生改变,将不再指向自身。
Stuent.prototype = new Name('张三');
Stuent.prototype.constructor === Name; // true
Stuent.prototype.constructor === Stuent; // false

以上就是我在项目中用到过的数据类型的判断方法,具体使用哪一种,还需要根据自己的实际需求来判断选择。

到此这篇关于JS数据类型判断的几种常用方法的文章就介绍到这了,更多相关JS 数据类型判断内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JS实现的省份级联实例代码
Jun 24 Javascript
js 距离某一时间点时间是多少实现代码
Oct 14 Javascript
推荐8款jQuery轻量级树形Tree插件
Nov 12 Javascript
jQuery插件PageSlide实现左右侧栏导航菜单
Apr 12 Javascript
javascript中offset、client、scroll的属性总结
Aug 13 Javascript
今天抽时间给大家整理jquery和ajax的相关知识
Nov 17 Javascript
JS获取中文拼音首字母并通过拼音首字母快速查找页面内对应中文内容的方法【附demo源码】
Aug 19 Javascript
Javascript实现代码折叠功能
Aug 25 Javascript
JS中IP地址与整数相互转换的实现代码
Apr 10 Javascript
vuejs事件中心管理组件间的通信详解
Aug 09 Javascript
用node-webkit把web应用打包成桌面应用(windows环境)
Feb 01 Javascript
微信小程序class封装http代码实例
Aug 24 Javascript
JavaScript实现像雪花一样的Hexaflake分形
Jul 07 #Javascript
jQuery 实现扁平式小清新导航
Jul 07 #jQuery
vue@cli3项目模板怎么使用public目录下的静态文件
Jul 07 #Javascript
JS实现移动端可折叠导航菜单(现代都市风)
Jul 07 #Javascript
React+EggJs实现断点续传的示例代码
Jul 07 #Javascript
JS实现联想、自动补齐国家或地区名称的功能
Jul 07 #Javascript
jQuery 动态粒子效果示例代码
Jul 07 #jQuery
You might like
解析CodeIgniter自定义配置文件
2013/06/18 PHP
php compact 通过变量创建数组
2016/11/15 PHP
jQuery 技巧大全(新手入门篇)
2009/05/12 Javascript
Dom在ajax技术中的作用说明
2010/10/25 Javascript
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
2014/09/26 NodeJs
jQuery实现带有洗牌效果的动画分页实例
2015/08/31 Javascript
jquery插件uploadify实现带进度条的文件批量上传
2015/12/13 Javascript
jQuery增加与删除table列的方法
2016/03/01 Javascript
JavaScript 随机验证码的生成实例代码
2016/09/22 Javascript
Javascript 获取鼠标当前的位置实现方法
2016/10/27 Javascript
关于微信上网页图片点击全屏放大效果
2016/12/19 Javascript
HTML5 js实现拖拉上传文件功能
2020/11/20 Javascript
基于vue2.0+vuex的日期选择组件功能实现
2017/03/13 Javascript
基于ES6作用域和解构赋值详解
2017/11/03 Javascript
AngularJS自定义过滤器用法经典实例总结
2018/05/17 Javascript
cocos2dx+lua实现橡皮擦功能
2018/12/20 Javascript
使用JS判断页面是首次被加载还是刷新
2019/05/26 Javascript
JavaScript实现的3D旋转魔方动画效果实例代码
2019/07/31 Javascript
jQuery实现每日秒杀商品倒计时功能
2019/09/06 jQuery
Js实现复选框的全选、全不选反选功能代码实例
2020/02/28 Javascript
vue利用全局导航守卫作登录后跳转到未登录前指定页面的实例代码
2020/05/19 Javascript
javascript使用canvas实现饼状图效果
2020/09/08 Javascript
[01:21:58]守擂赛DOTA2第一周决赛
2020/04/22 DOTA
在python中的socket模块使用代理实例
2014/05/29 Python
python实现从文件中读取数据并绘制成 x y 轴图形的方法
2018/10/14 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
Python多项式回归的实现方法
2019/03/11 Python
Python任务自动化工具tox使用教程
2020/03/17 Python
python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现)
2020/12/10 Python
Django前后端分离csrf token获取方式
2020/12/25 Python
塔吉特百货公司官网:Target
2017/04/27 全球购物
金智子午JAVA面试题
2015/09/04 面试题
大学生职业生涯规划范文
2014/01/22 职场文书
雨中的树观后感
2015/06/03 职场文书
教师听课学习心得体会
2016/01/15 职场文书
HashMap实现保存两个key相同的数据
2021/06/30 Java/Android