JS的数据类型检测

167 阅读2分钟

一共有几种数据类型检测?

一共有四种数据类型检测:

  • 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,也就是 ab 的一个实例。否则返回 falsea 不是 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]