JavaScript有几种方法判断变量的类型??
JavaScript有4种方法判断变量的类型,分别是:typeof、instanceof、Object.prototype.toString.call()(对象原型链判断方法)、 constructor (用于引用数据类型)
typeof:常用于判断基本数据类型,对于引用数据类型除了function返回’function‘,使用 typeof 能判断出四种,分别是 number,string,boolean,object,剩余的均被检测为object。
var name = "Code Fan"
console.log(typeof(name)) //string
typeof 1 // 'number'
typeof '1' // 'string'
typeof true // 'boolean'
typeof {} // 'object'
typeof [] // 'object'
typeof null // 'object'
typeof new Date() // 'object'
typeof (() => {}) // 'function'
typeof undefined // 'undefined'
typeof Symbol(1) // 'symbol'
instanceof:主要用于区分引用数据类型,检测方法是检测的类型在当前实例的原型链上,用其检测出来的结果都是true,不太适合用于简单数据类型的检测,检测过程繁琐且对于简单数据类型中的undefined, null, symbol检测不出来。
class Person{
constructor(name){
this.name= name;
}
}
let p = new Person("Code Fan")
console.log(p instanceof Person) //ture
({}) instanceof Object // true
[] instanceof Array // true
function Foo() {}
const foo= new Foo();
foo instanceof Foo// true
foo instanceof Object // true
//ps :由于是利用对象prototype的constructor进行判断,因此只有对象构造的数据类型变量适用该方法,不适用于非对象类型的变量
let str= 'string数据类型字符串';
let strObject= new String('Object构造的string字符串');
str instanceof String; // false
strObject instanceof String; // tru
//可以检测构造函数(constructor)的prototype属性是否位于实例对象的原型链上 , 一般用于判断自定义的构造函数实例
constructor:用于检测引用数据类型,检测方法是获取实例的构造函数判断和某个类是否相同,如果相同就说明该数据是符合那个数据类型的,这种方法不会把原型链上的其他类也加入进来,避免了原型链的干扰。
console.log((1).constructor === Number); // true
console.log(''.constructor === String); // true
console.log(false.constructor === Boolean); // true
console.log([].constructor === Array); // true
console.log(({}).constructor === Object); // true
console.log((function foo() {}).constructor === Function);// true
console.log(Symbol('1').constructor === Symbol);// true
//能判断如下类型 : Number , String , Boolean , Symbol , Function , Object , Array ; null 和 undefined没有constructor属性,所以不能判断
Object.prototype.toString.call():适用于所有类型的判断检测,检测方法是Object.prototype.toString.call(数据) 返回的是该数据类型的字符串。 这四种判断数据类型的方法中,各种数据类型都能检测且检测精准的就是Object.prototype.toString.call()这种方法。
let obj = {}
(1) Object.defineProperty(obj,Symbol.toStringTag,{
get:function(){
return 'hello'
}
})
(2) Object.prototype[Symbol.toStringTag] = 'hello'
console.log(Object.prototype.toString.call(obj)) //[object,hello]
function Foo(){};
const foo = new Foo();
Object.prototype.toString.call(1); // '[object Number]'
Object.prototype.toString.call('1'); // '[object String]'
Object.prototype.toString.call(true); // '[object Boolean]'
Object.prototype.toString.call(undefined); // '[object Undefined]'
Object.prototype.toString.call(null); // '[object Null]'
Object.prototype.toString.call(Symbol(1)); // '[object Symbol]'
Object.prototype.toString.call(Foo); // '[object Function]'
Object.prototype.toString.call(foo); // '[object Object]' , 实例化对象属于Object
Object.prototype.toString.call({}); // '[object Object]'
Object.prototype.toString.call([]); // '[object Array]'
Object.prototype.toString.call(NaN); // '[object Number]' ,此方法判断NaN也属于Number
instanceof的实现原理:验证当前类的原型prototype是否会出现在实例的原型链__proto__上,只要在它的原型链上,则结果都为true。因此,`instanceof` 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 `prototype`,找到返回true,未找到返回false。 Object.prototype.toString.call()原理:Object.prototype.toString 表示一个返回对象类型的字符串,call()方法可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,返回不同的结果。