在JavaScript中,常用的数据类型判断方法有四种,分别是 typeofinstanceofObject.prototype.toStrng.call()constructor

  • typeof:一般用来判断基本数据类型
//目前能返回string,number,boolean,symbol,bigint,unfined,object,function这八种判断类型
console.log(typeof 'abc') //string
console.log(typeof 1) //number
console.log(typeof true) //boolean
console.log(typeof Symbol()) //symbol
console.log(typeof 9007199254740991n) //bigint
console.log(typeof undefined) //undefined
console.log(typeof {}) //object
//null表示空对象,是一种特殊的object
console.log(typeof null) //object
console.log(typeof new Array()) //object
console.log(typeof new Function()) //function
  • instanceof:一般用来判断引用数据类型
    instanceof 用于判断一个变量是否属于某个对象的实例,如果使用 instanceof 来判断基本类型,将会返回 false。 也可以用来判断某个构造函数的prototype属性是否存在于指定对象的原型链中
//可以用来判断Object,Function,Array,Date,RegExp等引用数据类型
console.log([1,2,3] instanceof Array);  //true
console.log(function a(){} instanceof Function);  //true
console.log(/s/g instanceof RegExp);  //true
    
//如果使用instanceof来判断基本类型,将会返回false
console.log('2' instanceof String);  //false

//用来判断某个构造函数的prototype属性是否存在于指定对象的原型链中
function Person() {};
function People() {};
Person.prototype = new People();
let person1 = new Person()
console.log(person1 instanceof Person); //true
console.log(person1 instanceof People); //true
  • Object.prototype.toStrng.call()
    返回的是"[object Type]"的形式,可以返回参数的类型, (这个是判断类型最准的方法)
console.log(Object.prototype.toString.call(''));            // [object String]
console.log(Object.prototype.toString.call(1));             // [object Number]
console.log(Object.prototype.toString.call(true));          // [object Boolean]
console.log(Object.prototype.toString.call(undefined));     // [object Undefined]
console.log(Object.prototype.toString.call(null));          // [object Null]
console.log(Object.prototype.toString.call(new Function())); // [object Function]
console.log(Object.prototype.toString.call(new Date()));     // [object Date]
console.log(Object.prototype.toString.call([]));            // [object Array]
console.log(Object.prototype.toString.call(new RegExp()));  // [object RegExp]
console.log(Object.prototype.toString.call(new Error()));   // [object Error]
console.log(Object.prototype.toString.call(document));      // [object HTMLDocument]
console.log(Object.prototype.toString.call(window));        //[object global] window是全局对象global的引用

按理说,Array和Function都有toString()方法,为什么要调用Object原型上的呢,因为他们的toString被改写了

  • constructor
  • constructor 是通过 “ 判断对象.constructor " 返回构造函数的名字来判别。
  • 当一个函数 F 被定义时,js引擎会为 F 添加 prototype 原型属性,在 F.prototype 上会有一个 constructor 属性,指向与之关联的F。
  • JS对象的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写prototype后,原有的constructor会丢失,constructor 会默认为 Object
  • null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,也就是不能使用该方法进行类型判断
console.log(''.constructor === String); // true
console.log((123).constructor === Number); // true
console.log(({}).constructor === Object); // true
console.log((function a(){}).constructor === Function ); // true
console.log(document.constructor === HTMLDocument); // true
    
//当重写prototype属性时,constructor 会默认为 Object
function F() {}
F.prototype = {a: '123'};
let f = new F();
console.log(f.constructor === Function) //false
console.log(f.constructor) //f Object() {}
  • 拓展:

    typeof 与 instanceof 的原理
  • typeof 是通过对变量的机器码进行判断得到数据类型的。JavaScrpit在底层储存变量时,会在变量机器码的前1~3位中存储其类型信息,typeof 通过机器码中的类型信息进行判断。特别需要说明的是类型信息 000 表示对象,而 null 的机器码全部为0,所以 typeof null 得到的结果是 object
  • instanceof 是基于原型链进行判断的,通过判断右边变量的 prototype 属性是否出现在左边变量的原型链上得到最终结果。