在JavaScript中,常用的数据类型判断方法有四种,分别是 typeof
、 instanceof
、 Object.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
属性是否出现在左边变量的原型链上得到最终结果。