JS 检测对象类型

600 阅读2分钟

判断对象类型(原始、复杂),一般有四种方法:

  • typeof
  • instanceof
  • constructor
  • Object.prototype.toString.call()

需注意:检测的完整性,依次递增,推荐使用最后一种 Object.prototype.toString.call

一、typeof

typeof 可以检测number、string、boolean、undefined,symbol和object、function七种数据类型

  • 一般用做区分基本数据类型
  • 无法区分对象和数组(typeof 判断对象和数组都返回object)
typeof 0;  //number;
typeof true;  //boolean;
typeof undefined;  //undefined;
typeof "hello world"   //string;
typeof function(){};   //function;

typeof null; //object
typeof {};  //object;
typeof []; //object
let s = Symbol();
typeof s    //"symbol"
s instanceof Symbol  //false

二、instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否存在于某个实例对象的原型链上。

  • 一般用来判断数组和对象
var o = { };
var a = ['reg','blue'];

o instanceof Object; // true
o instanceof Array;  // false

a instanceof Array;   // true
a instanceof Object; // true
  • 不能区分基本类型 string 和 boolean,除非是字符串对象和布尔对象
var c = 'abc';
c instanceof String; //false

var d = new String();
d instanceof String  //true
  • new实例 改变函数的 prototype 时,情况有点特殊
// 定义构造函数
function C(){}

var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype

C.prototype = {};  // 改变构造函数的prototype

var o2 = new C();
o2 instanceof C; // true
o instanceof C;  // false,C.prototype被重写,但是 o 的原型对象指向的是之前的原型对象

三、constructor

  • 除了 undefined 和 null,其他类型的变量均能使用 constructor 判断出类型
var o={};
o.constructor == Object  //true

var arr = [];
arr.constructor == Array  //true
arr.constructor == Object //false

var n = true;
n.constructor == Boolean  //true

var num1 = 1;
var num2 = new Number();
num1.constructor == Number   //true
num2.constructor == Number  //true

var str = 'hello world';
str.constructor == String     //true
  • 不过要注意,constructor属性是可以被修改的,会导致检测出的结果不正确
function Person(){ }
function Student(){ }

Student.prototype = new Person();

var John = new Student();
John.constructor == Student; // false
John.constructor == Person; // true

四、Object.prototype.toString.call() (推荐)

推荐使用该方法,检测的类型很全面哦

Object.prototype.toString.call(null)  //"[object Null]"

Object.prototype.toString.call(undefined)  //"[object Undefined]"

Object.prototype.toString.call(123)   //"[object Number]"

Object.prototype.toString.call('str')  //"[object String]"

Object.prototype.toString.call(true)  //"[object Boolean]"

Object.prototype.toString.call({})  //"[object Object]"

Object.prototype.toString.call([])  //"[object Array]"

判断数据类型,以数组、对象为例:

function typeObj(obj){
    if(type=='[object Array]'){
        return 'Array';
    }elseif(type=='[object Object]'){
        return 'Object';
    }
}

上面的方法也可以封装成如下这种

function type(obj) {
    return Object.prototype.toString.call(obj).replace(/\[object\s|\]/g, "");
}

function isArray(list) {
    return type(list) === "Array";
}

function isObject(obj) {
    return type(obj) === "Object";
}

function isString(str) {
    return type(str) === "String";
}