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