JS中数据类型的判断
typeof能返回的数据类型
-
number
var num = 1; console.log(typeof num);//返回的是number
-
string
var str = 'jack'; console.log(typeof str);//返回的是string
-
boolean
var boo =true; console.log(typeof boo);//返回的是boolean
-
undefined
var und ; console.log(typeof und);//返回的是undefined
-
function
var fn = function(){}; console.log(typeof fn); //返回的是function
-
object
var arr = new Array();//array console.log(typeof arr); //返回的是object var obj = new Object(); console.log(typeof obj); //返回的是object var nul = null; //特别地 console.log(typeof nul); //返回的是object
-
NaN
var a = 10; var b = '2'; console.log(typeof a / b); // 返回的是NaN
-
symbol
var mySymbol = Symbol(); console.log(typeof mySymbol); // 返回的是symbol
可见,typeof可以返回的数据类型有:number、string、boolean、object、undefined、function、NaN、symbol共八种;
其中,arry,object,null三种类型不能具体判断,请可以往下看:
instanceof
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。MDN
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
通过上面的代码显示结果,直接的字面量值判断数据类型,只有引用数据类型(Array,Function,Object)被精准判断,其他(数值Number,布尔值Boolean,字符串String)字面值不能被instanceof精准判断。在这里字面量值,2, true ,'str’不是实例,所以判断值为false。看下面的例子(字面值被实例化了,他们的判断值变为了 true):
console.log(new Number(2) instanceof Number); // true
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new String('str') instanceof String); // true
constructor
console.log((2).constructor === Number); //true
console.log((true).constructor === Boolean); //true
console.log(('str').constructor === String); //true
console.log(([]).constructor === Array); //true
console.log((function() {}).constructor === Function); //true
console.log(({}).constructor === Object); //true
用costructor来判断类型看起来是完美的,然而,如果我创建一个对象,更改它的原型,这种方式也变得不可靠了
function Fn(){};
Fn.prototype=new Array();
var fn=new Fn();
console.log(fn.constructor===Fn); // false
console.log(fn.constructor===Array); // true
很轻易的更改了contructor,到这里,你可能会想有没有一种最精准的方式去判断数据类型呢?
Object.prototype.toString.call()
使用 Object 对象的原型方法 toString ,使用 call 进行狸猫换太子,借用Object的 toString 方法
var a = Object.prototype.toString;
console.log(a.call(2)); //[object Number]
console.log(a.call(true)); //[object Boolean]
console.log(a.call('str')); //[object String]
console.log(a.call([])); //[object Array]
console.log(a.call(function(){})); //[object Function]
console.log(a.call({})); //[object Object]
console.log(a.call(undefined)); //[object Undefined]
console.log(a.call(null)); //[object Null]
结果精准的显示我们需要的数据类型。
就算我们改变对象的原型,他依然会显示正确的数据类型。
Array.isArray
Array.isArray由于是es6新增的方法,所以在兼容性上存在一些劣势,但是在判断类型上具有优势,不会因为重写constructor和toString方法失效;
Array.isArray([1, 2, 3]); // true
Array.isArray({foo: 123}); // false
Array.isArray("foobar"); // false
Array.isArray(undefined); // false