JavaScript如何判断数据类型

75 阅读2分钟

如何判断数据类型

  1. typeof 操作符
  2. Array.isArray() 方法
  3. Object.prototype.toString.call() 方法
  4. instanceof 操作符
  5. construtor 属性

typeof

typeof是最简单的判断方法,但是它无法区分对象和数组类型,因为都会返回”object”(数组在JavaScript中是对象类型)

let stringValue = "Hello, World!";
let numberValue = 100;
let booleanValue = true;
let objectValue = { key: "value" };
let arrayValue = [1, 2, 3];
let functionValue = function() {};

console.log(Object.prototype.toString.call(stringValue));    // "[object String]"
console.log(Object.prototype.toString.call(numberValue));    // "[object Number]"
console.log(Object.prototype.toString.call(booleanValue));   // "[object Boolean]"
console.log(Object.prototype.toString.call(objectValue));    // "[object Object]"
console.log(Object.prototype.toString.call(arrayValue));     // "[object Array]"
console.log(Object.prototype.toString.call(functionValue)); // "[object Function]"

Array.isArray()

特别地,我们可以使用Array.isArray() 方法来判断数据是否为数组类型

let arrayValue = [1, 2, 3];
console.log(Array.isArray(arrayValue)); // true

Object.prototype.toString()

Object.prototype.toString 方法是 JavaScript 所有对象默认继承的一个方法,它返回对象的类型信息。

在 JavaScript 中,call() 方法可以用来改变函数的执行上下文,即 this 的指向。Object.prototype.toString.call() 通过传递一个对象作为参数,改变了 Object.prototype.toString 方法中的 this 的指向,使得该方法可以用于任何对象。

let stringValue = "Hello, World!";
let numberValue = 100;
let booleanValue = true;
let objectValue = { key: "value" };
let arrayValue = [1, 2, 3];
let functionValue = function() {};

console.log(Object.prototype.toString.call(stringValue));    // "[object String]"
console.log(Object.prototype.toString.call(numberValue));    // "[object Number]"
console.log(Object.prototype.toString.call(booleanValue));   // "[object Boolean]"
console.log(Object.prototype.toString.call(objectValue));    // "[object Object]"
console.log(Object.prototype.toString.call(arrayValue));     // "[object Array]"
console.log(Object.prototype.toString.call(functionValue)); // "[object Function]"

instanceof

instanceof 操作符用于检测一个对象是否是某个构造函数的实例,它通过检查该构造函数的 prototype 属性是否出现在该对象的原型链上来实现。

  • 每个对象都有一个内部属性 [[Prototype]] 或者说 proto,即我们常说的原型,它指向构造函数的 prototype 对象。
  • 一个对象可以通过其原型链追溯到它的构造函数的 prototype,再进一步到更上层的原型,直到最终指向 null(原型链的终点)。
  • instanceof 操作符在判断对象类型时非常有效,但无法判断基本数据类型(如 string、number、boolean、symbol、bigint、undefined 和 null),这是因为 instanceof 的工作原理是基于对象的原型链,而基本数据类型没有原型链。
let arrayInstance = [1, 2, 3];
console.log(arrayInstance instanceof Array); // true
console.log(arrayInstance instanceof Object); // true

constructor 属性

每个对象都有一个constructor属性,指向它的构造函数。通过这个属性,你可以判断对象的类型。

let stringValue = "Hello, World!";
let numberValue = 100;
let booleanValue = true;
let objectValue = { key: "value" };
let arrayValue = [1, 2, 3];
let functionValue = function() {};

console.log(stringValue.constructor === String);    // true
console.log(numberValue.constructor === Number);    // true
console.log(booleanValue.constructor === Boolean);   // true
console.log(objectValue.constructor === Object);    // true
console.log(arrayValue.constructor === Array);     // true
console.log(functionValue.constructor === Function); // true
  • constructor属性可以被修改,所以在某些情况下可能不可靠。
function Person(name) {
    this.name = name;
}

const alice = new Person('Alice');
console.log(alice.constructor === Person); // true

alice.constructor = Array;
console.log(alice.constructor === Person); // false
console.log(alice.constructor === Array);  // true

本文主要参考 fe-journey.cn/knowledge 并加入一些自己的理解与思考。