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 相关文章推荐
splice slice区别
Oct 09 Javascript
一个可以兼容IE FF的加为首页与加入收藏实现代码
Nov 02 Javascript
seajs1.3.0源码解析之module依赖有序加载
Nov 07 Javascript
jquery限制输入字数,并提示剩余字数实现代码
Dec 24 Javascript
两种不同的方法实现js对checkbox进行全选和反选
May 13 Javascript
jQuery基于图层模仿五星星评价功能的方法
May 07 Javascript
浅谈javascript中的闭包
May 13 Javascript
浅谈webpack 自动刷新与解析
Apr 09 Javascript
KOA+egg.js集成kafka消息队列的示例
Nov 09 Javascript
echarts多条折线图动态分层的实现方法
May 24 Javascript
vue实现列表滚动的过渡动画
Jun 29 Javascript
微信小程序实现页面左右滑动
Nov 16 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
Php中文件下载功能实现超详细流程分析
2012/06/13 PHP
PHP中spl_autoload_register函数的用法总结
2013/11/07 PHP
解决nginx不支持thinkphp中pathinfo的问题
2015/07/21 PHP
PHP防止图片盗用(盗链)的方法小结
2016/11/11 PHP
JavaScript读取中文cookie时的乱码问题的解决方法
2009/10/14 Javascript
js select常用操作控制代码
2010/03/16 Javascript
jQuery 位置函数offset,innerWidth,innerHeight,outerWidth,outerHeight,scrollTop,scrollLeft
2010/03/23 Javascript
jQuery Ajax提交表单查询获得数据实例代码
2012/09/19 Javascript
Extjs实现进度条的两种便捷方式
2013/09/26 Javascript
JS版的date函数(和PHP的date函数一样)
2014/05/12 Javascript
JS中使用Array函数shift和pop创建可忽略参数的例子
2014/05/28 Javascript
js设置控件的隐藏与显示的两种方法
2014/08/21 Javascript
JavaScript实现信用卡校验方法
2015/04/07 Javascript
jQuery+Ajax实现无刷新分页
2015/10/30 Javascript
js自定义回调函数
2015/12/13 Javascript
js实现仿购物车加减效果
2017/03/01 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
删除table表格行的实例讲解
2017/09/21 Javascript
javascript获取图片的top N主色值方法详解
2018/01/26 Javascript
vue项目打包后打开页面空白解决办法
2018/06/29 Javascript
Python Queue模块详细介绍及实例
2016/12/27 Python
Python 3实战爬虫之爬取京东图书的图片详解
2017/10/09 Python
Python实现合并两个列表的方法分析
2018/05/28 Python
异步任务队列Celery在Django中的使用方法
2018/06/07 Python
python实现抖音视频批量下载
2018/06/20 Python
python十进制转二进制的详解
2020/02/07 Python
html5实现的便签特效(实战分享)
2013/11/29 HTML / CSS
HTML5如何为形状图上颜色怎么绘制具有颜色和透明度的矩形
2014/06/23 HTML / CSS
施华洛世奇水晶荷兰官方网站:SWAROVSKI荷兰
2017/05/12 全球购物
澳大利亚排名第一的儿童在线玩具商店:Toy Galaxy
2018/10/06 全球购物
高二学生评语大全
2014/04/25 职场文书
硕士研究生就业推荐信
2014/05/18 职场文书
党的群众路线教育实践活动制度建设计划方案
2014/10/31 职场文书
2019学校运动会开幕词
2019/05/13 职场文书
Java循环队列与非循环队列的区别总结
2021/06/22 Java/Android
go select编译期的优化处理逻辑使用场景分析
2021/06/28 Golang