JS数据类型判断

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数据类型判断的几种方法的更多相关文章

  1. Js中数据类型判断的几种方法

    判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. $.type()/jquery.type(),接下来主要比较一下这几种方法的异 ...

  2. JavaScript数据类型判断的四种方法

    码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14416375.html 本文分享了JavaScript类型判断的四种方法:typeo ...

  3. ajax请求参数中含有特殊字符"#"的问题 (另附上js编码解码的几种方法)

    使用ajax向后台提交的时候 由于参数中含有#  默认会被截断 只保留#之前的字符  json格式的字符串则不会被请求到后台的action 可以使用encodeURIComponent在前台进行编码, ...

  4. js数据类型判断和数组判断

    这么基础的东西实在不应该再记录了,不过嘛,温故知新~就先从数据类型开始吧 js六大数据类型:number.string.object.Boolean.null.undefined string: 由单 ...

  5. JS实现深拷贝的几种方法

    引 如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力. 此篇文章中也会简单阐述到栈 ...

  6. js数据类型 判断

    1. js数据类型(两种数据类型) 基本数据类型:null undefined number boolean symbol string 引用数据类型: array object null: 空对象 ...

  7. JS数组去重的9种方法(包括去重NaN和复杂数组类型)

    其实网上已经有很多js数组的去重方法,但是我看了很多篇并自己通过代码验证,发现都有一些缺陷,于是在研究多篇代码之后,自己总结了9种方法,如果有哪里不对请及时纠正我哈~ 转载请表明出处 测试代码 let ...

  8. js数组去重的4种方法

    js数组去重,老生长谈,今天对其进行一番归纳,总结出来4种方法 贴入代码前 ,先对浏览器Array对象进行支持indexOf和forEach的polyfill Array.prototype.inde ...

  9. 判断元素16种方法expected_conditions

    前言 标签(空格分隔): 判断元素 经常有小伙伴问,如何判断一个元素是否存在,如何判断alert弹窗出来了,如何判断动态的元素等等一系列的判断,在selenium的expected_condition ...

随机推荐

  1. IDEA突然无法运行

    可能是你类的main方法被idea的智能提示改了 PS: 小编经常用智能提示,它给我把main方法的static关键字删掉了好几次,当时怎么也没想到是把main方法改了 ~难受

  2. java实现第四届蓝桥杯幸运数

    幸运数 题目描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成. 首先从1开始写出自然数1,2,3,4,5,6,- 1 就是第一个幸运数. 我们从2这个数开始 ...

  3. Base-64字符串无效,The input is not a valid Base-64 string as it contains a non-base 64 character

    base64规则: * 字符串只可能包含A-Z,a-z,0-9,+,/,=字符* 字符串长度是4的倍数* =只会出现在字符串最后,可能没有或者一个等号或者两个等号 首先,C# 做上传文件的时候,需要替 ...

  4. 单页面应用下刷新当前iframe

    $('button.layui-btn-elastic-2').click(function(){ var srcIframe=$(".layui-side ul li dd"). ...

  5. C# 9.0 新特性之模式匹配简化

    阅读本文大概需要 2 分钟. 记得在 MS Build 2020 大会上,C# 语言开发项目经理 Mads Torgersen 宣称 C# 9.0 将会随着 .NET 5 在今年 11 月份正式发布. ...

  6. 浅谈HTTPS和HTTP

    1.HTTP和HTTPS的基本概念 HTTP:超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务端请求和应答的标准,用于WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览 ...

  7. [CentOS 7]挂载ntfs格式U盘

    在我们将U盘插入装有CentOS的系统时,经常会出现如图所示的错误提示.这是因为linux系统并不能兼容NTFS的文件系统.其解决方法如下(建议先进入root模式): 1.首先下载"ntfs ...

  8. 【Flutter实战】六大布局组件及半圆菜单案例

    老孟导读:Flutter中布局组件有水平 / 垂直布局组件( Row 和 Column ).叠加布局组件( Stack 和 IndexedStack ).流式布局组件( Wrap )和 自定义布局组件 ...

  9. 谷歌Chrome成最受欢迎的浏览器 它为啥好用?

    毫无疑问,在搜索引擎领域,谷歌是绝对的主导者.但是,一般人却很容易低估我们受到的“控制”.比如,它的浏览器Chrome. 在不到九年的时间,谷歌Chrome浏览器已经成为全球使用最多的网页浏览器.目前 ...

  10. pyhton 月份和天数的计算

    http://stackoverflow.com/questions/546321/how-do-i-calculate-the-date-six-months-from-the-current-da ...