一共有几种数据类型检测?
一共有四种数据类型检测:
- typeof
- instanceof
- constructor
- Object.prototype.toStrng.call()
typeof 和 instanceof 有什么区别? typeof 返回的是字符串,instanceof 返回的是布尔值
1、typeof 判断
typeof 是一元运算符,同样返回一个字符串类型。一般用来判断一个变量是否为空或者是什么类型。
除了 null 类型以及 Object 类型不能准确判断外,其他数据类型都可能返回正确的类型。
typeof '10'; // string
typeof 10; // number
typeof false; // boolean
typeof undefined; // undefined
typeof null; // object
typeof Symbol(); // symbol
typeof []; // object
typeof {}; // object
typeof Function; // function
typeof Date; // function
typeof /bac/; // object
为什么
typeof null等于Object? 不同的对象在底层原理的存储是用二进制表示的,在 javaScript 中,如果二进制的前三位都为 0 的话,系统会判定为是 Object 类型。null的存储二进制是 000,也是前三位,所以系统判定null为 Object 类型。
2、instanceof 判断
instanceof 运算符用来检测一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
可以使用 instanceof 来判断某个对象是不是另一个对象的实例,返回值是一个布尔值。
var a = [];
console.log(a.__proto__ === Array.prototype) // true
console.log(a instanceof Array) // true
instanceof 不能检测 null 和 undefined。
null instanceof Null // 报错
undefined instanceof Undefined // 报错
我们再测一下 ES6 中的 class 语法糖是什么类型。
class A {}
console.log(A instanceof Function) // true
假设现在有 a instanceof b 一条语句,则其 instanceof 内部实际做了如下判断:
while(a.__proto__ !== null) {
if(a.__proto__ === b.prototype) {
return true;
}
a.__proto__ = a.__proto__.proto__;
}
if(a.__proto__ === null) {
return false;
}
a 会一直沿着隐式原型链 __proto__ 向上查找直到 a.__proto__.__proto__ ...... === b.prototype 为止,如果找到则返回 true,也就是 a 为 b 的一个实例。否则返回 false,a 不是 b 的实例。
注意:原型链中的
prototype随时可以被改动的,改变后的值可能不存在于object的原型链上,instanceof返回的值可能就返回false。
3、constructor 判断
对于引用类型,还可以使用 xxx.constructor.name 来判断:
console.log(fn.constructor.name); // Function
console.log(date.constructor.name); // Date
console.log(arr.constructor.name); // Array
console.log(reg.constructor.name); // RegExp
console.log(obj.constructor.name); // Object
4、Object.prototype.toString().call() 判断
一种最好的基本类型检测方式: Object.prototype.toString.call();
toString() 方法返回一个描述某对象的字符串,如果此方法在自定义的对象中未被覆盖,则 toString() 返回 "[object type]",其中 type 是 对象类型。在使用 toString() 方法检测对象类型时,常用 Object.prototype.toString.call() 或 Object.prototype.toString.apply() 来检测,如下代码:
const toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]