探索 JavaScript 中的数据类型判断技巧

43 阅读3分钟

前言

  • 这篇文章会介绍 JS 中常用的数据类型判断方法, 包括

      1. 使用 typeof 判断数据类型
      1. 使用 instanceof 判断数据类型
      1. 使用 constructor 判断数据类型
      1. 使用 Object.prototype.toString 判断数据类型
  • 在开始之前, 我们先回顾下 JS 中的数据类型, 在 JS 中的数据类型分为两大类:

      1. 基本数据类型(在存储变量中存储的是值本身):如 number、string、boolean、null、undefined、symbol(ES6) 和 bigInt(ES6)
      1. 引用类型(在存储变量中存储的仅仅是地址(引用), 通过 new 关键字创建的对象):如 Object、Array、Data、Function 等

提示:Function 其实也是对象, 只不过它是特殊的对象, 除了基本数据类型意以外, 其他的都是对象, 即一切皆对象

使用 typeof 判断数据类型

使用 typeof 判断数据类型返回的都是 字符串

使用 typeof 判断基本数据类型

判断基本数据类型: 除了判断 null 是返回字符串 object 外,其他都能正确返回对应的类型。

console.log(typeof 5); // 'number'
console.log(typeof "zsy"); // 'string'
console.log(typeof true); // 'boolean'
console.log(typeof null); // 注意输出'object', 为啥这也是object呢, 其实这是设计 JS 中的一个 bug, 也是常考的一道面试题
console.log(typeof undefined); // 'undefined'
console.log(typeof Symbol("name")); // 'symbol'
console.log(typeof BigInt("1")); // 'bigint'

使用 typeof 判断复杂数据类型

使用 typeof 判断复杂数据类型: 除了判断函数返回是 function 字符串,其他的引用类型返回的都是 字符串 object

const foo = () => 1;
console.log(typeof foo); // 'function'

const foo1 = {};
console.log(typeof foo1); // 'object'

const foo2 = [];
console.log(typeof foo2); // 'object'

const foo3 = new Date();
console.log(typeof foo3); // 'object'

console.log(typeof new Number(1)); //object

使用 instanceof 判断数据类型

比如说:a instanceof B 判断的是 a 是否为 B 的实例, 即沿着 a 的 __proto__, 如果能与 B 的 prototype 发生交汇, 那么就是 true, 否则就是 false

function Person(name) {
  this.name = name;
}

let p = new Person("zsy");
console.log(p instanceof Person); // true, 【沿着p的__proto__ 属性】形成的原型链能与【Person 的 prototype 属性】能发生交汇,那么就是 true,否则就是false

//  顺着 p 的原型链能找到 Object 的构造函数,因此如下代码返回 true
console.log(p.__proto__.__proto__ === Object.prototype); // true

注意如下:

console.log(5 instanceof Number); // false,因为 5 是基本数据类型,不是 Number 构造函数构造出来的实例对象,可以改为如下:
console.log(new Number(5) instanceof Number); // true

// class 本质上是函数,可见 class 是语法糖
class People {}
console.log(typeof People); // 'function'

使用 constructor 判断数据类型

使用 constructor 判断数据类型返回的是 [Function: 数据类型], 也可以精准的判断数据类型,但是判断 nullundefined 的时候会报错。

var foo = 5;
console.log(foo.constructor); // [Function: Number]

var foo1 = "zsy";
console.log(foo1.constructor); // [Function: String]

var foo2 = true;
console.log(foo2.constructor); // [Function: Boolean]

var foo4 = [];
console.log(foo4.constructor); // [Function: Array]

var foo5 = {};
console.log(foo5.constructor); // [Function: Object]

var foo6 = () => {};
console.log(foo6.constructor); // [Function: Function]

var foo7 = new Date();
console.log(foo7.constructor); // [Function: Date]

var foo8 = Symbol("name");
console.log(foo8.constructor); // [Function: Symbol]

var foo9 = undefined;
console.log(foo9.constructor); // Cannot read properties of undefined (reading 'constructor')

var foo10 = null;
// console.log(foo10.constructor) // Cannot read properties of null (reading 'constructor')

使用 Object.prototype.toString 判断数据类型

这种一种万能方法, 因为它可以精准判断所传入参数的数据类型。但是其缺陷是不能细分谁是谁的实例。

console.log(Object.prototype.toString.call(1)); // [object Number]

console.log(Object.prototype.toString.call("zsy")); // [object String]

console.log(Object.prototype.toString.call(undefined)); // [object Undefined]

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(null)); // [object Null]

console.log(Object.prototype.toString.call(Symbol("name"))); // [object Symbol]

console.log(Object.prototype.toString.call(new Date())); //[object Date]

console.log(Object.prototype.toString.call(/\d/)); //[object RegExp]

function Person() {}
console.log(Object.prototype.toString.call(new Person())); //[object Object]