前端之路 — JavaScript 准确判断数据类型的方法
JavaScript 中常见的几种数据类型:
基本类型:string,number,boolean,Symbol
特殊类型:undefined,null
引用类型:Object,Function,Function,Array,Date,...
1、typeof
typeof ''; // string 有效
typeof 1; // number 有效
typeof true; // boolean 有效
typeof undefined; // undefined 有效
typeof null; // object 无效
typeof [] ; // object 无效
typeof new Function(); // function 有效
typeof new Date(); // object 无效
typeof new RegExp(); // object 无效
在 JavaScript 里 使用 typeof 来判断数据类型,只能区分基本类型,即 “ number ” , “ string ” , “ undefined ” , “ boolean ” , “ object ” 五种。
对于数组、函数、对象来说,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串。
所以,要想区别对象、数组、函数单纯使用 typeof 是不行的 ,JavaScript 中,通过 Object.prototype.toString 方法,判断某个对象值属于哪种内置类型。
2、Object.prototype.toString 和 $.type()
console.log(Object.prototype.toString.call(123)) // [object Number]
console.log(Object.prototype.toString.call('123')) // [object String]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(function(){})) // [object Function]
console.log(Object.prototype.toString.call(this)); // [object Window]
判断是否为函数:
function isFunction(it) {
return Object.prototype.toString.call(it) === '[object Function]';
}
判断是否为数组:
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
到这里不得不说 Object.prototype.toString.call() 真是判断数据类型的**"万精油"**呀!(绝招不一定要放在最后/doge/)
在 Object.prototype.toString 方法被调用时,会执行下面的操作步骤(了解):
-
获取this对象的[[Class]]属性的值。
-
计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串.
-
返回第二步的操作结果Result(2)。
[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性。在规范中,[[Class]]是这么定义的:
内部属性 | 描述 |
---|---|
[[Class]] | 一个字符串值,表明了该对象的类型。 |
重点: [[Class]] 表明了该对象的类型
读到这里,你就已经掌握了准确判断数据类型的方法了,是不是感觉自己有进步了呢。
或许你用过 jQuery 的 $.type() 方法判断数据类型,其实它就是对 Object.prototype.toString.call() 的一个封装,还有在 vue-router 的源码等地方里也用来转换和检测数据类型。
当然,判断数据类型不止于以上这3种方法(typeof,Object.prototype.toString,$.type()),还有 instanceof 和 constructor 进行数据类型判断,不过他们都存在一些缺点。
3、instanceof
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
// 这俩比较特殊,稍作解释
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
以上结果显示,直接的字面量值判断数据类型,只有引用数据类型(Array,Function,Object)被精准判断,其他(数值Number,布尔值Boolean,字符串String)字面值不能被instanceof精准判断。
我们来看一下 instanceof 在 MDN 中的解释:instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。其意思就是判断对象是否是某一数据类型(如Array)的实例,请重点关注一下是判断一个对象是否是数据类型的实例。在这里字面量值,2, true ,'str'不是实例,所以判断值为false。眼见为实,看下面的例子:
console.log(new Number(2) instanceof Number) // true
console.log(new Boolean(true) instanceof Boolean) // true
console.log(new String('str') instanceof String) // true
字面值被实例化了,他们的判断值变为了 true 。
接着,我们看一下 undefined 和 null ,说说为什么这两货比较特殊,实际上按理来说,null的所属类就是Null,undefined就是Undefined,但事实并非如此。控制台输出如下结果:
console.log(new undefined instanceof Undefined)
// TypeError: undefined is not a constructor
console.log(new null instanceof Null)
// TypeError: null is not a constructor
浏览器认为null,undefined不是构造器。但是在 typeof 中你可能已经发现了,typeof null的结果是object,typeof undefined的结果是undefined ,这是怎么回事呢 ? 其实这是 JavaScript 设计者的一大重大失误, Google公司开发的JavaScript语言的替代品Dart语言,就明确规定只有null,没有undefined!
想了解 undefined 和 null 的区别 可以看下 阮一峰大神的网络日志: www.ruanyifeng.com/blog/2014/0…
4、constructor
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
用costructor来判断类型看起来是完美的,然而,如果我创建一个对象,更改它的原型,这种方式也变得不可靠了。
function Fn(){};
Fn.prototype = new Array();
var f = new Fn();
console.log(f.constructor === Fn); // false
console.log(f.constructor === Array); // true
如此轻易的更改了contructor,说明了什么, Object.prototype.toString.call() 真香,/doge/。
以上就是我对 JavaScript 数据类型判断的一个学习总结了,大家加油!
ps:广州有坑位请联系我邮箱 2412684394@qq.com ,欢迎骚扰。
转载自:https://juejin.cn/post/6844904087637458952