js数据类型的判断主要有三种方法:
typeof ,instanceof,Object.prototype.toString.call()
【一】 typeof
typeof可以区分 原始类型,undfined和 function 数据类型
typeof的返回值是一个字符串,该字符串说明运算数的类型。返回结果只有以下几种:number,string,boolean,object,undfined,function
可以使用typeof判断变量是否存在(比如 if(typeof a!=“undfined”){ xxx }),而不要去使用if(a),因为a不存在(未声明)会报错。无法判断对象和数组,还有null,因为都返回的是object
【1】 对于数字类型, typeof 返回的值是 number。
console.log(typeof(1)); //number
【2】 对于字符串类型, typeof 返回的值是 string。
console.log(typeof("123")); // string
【3】 对于布尔类型, typeof 返回的值是 boolean 。
console.log(typeof(true)); // boolean
【4】 对于对象、数组、null 返回的值是 object 。
console.log(typeof(window)); // object
console.log(typeof(document)); // object
console.log(typeof([1,2,3])); // object
console.log(typeof({id:1,name:'aa'})); // object
console.log(typeof(null)); // object
【5】 对于函数类型,返回的值是 function。
console.log(typeof(Date)); // function
【6】 如果运算数是没有定义的(比如说不存在的变量、函数或者undefined),将返回undefined。
console.log(typeof(a)); // undefined
console.log(typeof(undefined)); // undefined
无法判断对象和数组,还有null,因为都返回的是object,所以要 想区分对象、数组、null,单纯使用 typeof 是不行的。
【二】instanceof运算符
instanceof 操作符可以区分自定义对象类型
instanceof 运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上,返回一个布尔值。instanceof运算符不能判断 null和undefined
对于基本类型的数据,instanceof是不能直接判断它的类型的,因为实例是一个对象或函数创建的,是引用类型,所以需要通过基本类型对应的 包装对象 来判断。
关于instanceof 的实现原理,可以参考下面:
function myInstanceof(left, right) {
// 这里先用typeof来判断基础数据类型,如果是,直接返回false
if(typeof left !== 'object' || left === null) return false;
// getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
let proto = Object.getPrototypeOf(left);
while(true) {
if(proto === null) return false;
if(proto === right.prototype) return true;//找到相同原型对象,返回true
proto = Object.getPrototypeof(proto);
}
}
【1】instanceof 不能用于判断原始数据类型的数据
5 instanceof Number // false
new Number(5) instanceof Number // true
true instanceof Boolean // false
【2】instanceof 可以用来判断对象的类型
let date = new Date()
date instanceof Date // true
let number = new Number()
number instanceof Number // true
let string = new String()
string instanceof String // true
需要注意的是,instanceof 的结果并不一定是可靠的,因为在 ECMAScript7 规范中可以通过自定义 Symbol.hasInstance 方法来覆盖默认行为。
【三】Object.prototype.toString.call()
Object.prototype.toString.call() 区分的数据类型适用范围更大,但是无法区分自定义对象类型
在判断数据类型时, Object.prototype.toString 返回 “[object XXX]”
【1】 判断基本类型
Object.prototype.toString.call('abc') //"[object String]"
Object.prototype.toString.call(1) //"[object Number]"
Object.prototype.toString.call(true) //"[object Boolean]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
【2】 判断原生引用类型
// 函数类型
Object.prototype.toString.call(function(){}) // "[object Function]"
// 数组类型
Object.prototype.toString.call([1,2,3]) //"[object Array]"
// 对象类型
Object.prototype.toString.call({a:1}) //"[object Object]"
// 日期类型
let date = new Date();
Object.prototype.toString.call(date); //”[object Date]”
// 正则表达式
let res = /^a[bcd]ef/g;
Object.prototype.toString.call(res); // "[object RegExp]"
// 自定义类型
function Person(id, name) {
this.id = id;
this.name = name;
}
let person = new Person("a", 1);
Object.prototype.toString.call(person); // ”[object Object]”