判断js中的数据类型有一下几种方法:typeof、instanceof、 constructor、Object.prototype.toString.call()接下来主要比较一下这几种方法的异同。
1、最常见的判断方法:typeof
console.log('测试 Number ->', typeof 3689); // number
console.log('测试 Boolean ->', typeof true); // boolean
console.log('测试 String ->', typeof 'fuzai'); // string
console.log('测试 null ->', typeof null); // object
console.log('测试 undefined ->', typeof undefined); // undefined
console.log('测试 NaN ->', typeof NaN); // number
console.log('测试 function ->', typeof function () { }); // function
console.log('测试 Object ->', typeof {}); // object
console.log('测试 Array ->', typeof [1,2,3]); // object
console.log('测试 Date ->', typeof new Date()); // object
console.log('测试 Error ->', typeof new Error()); // object
console.log('测试 RegExp ->', typeof new RegExp()); // object
console.log('测试 Symbol ->', typeof Symbol()); // symbol
console.log('测试 Map ->', typeof new Map()); // object
console.log('测试 Set ->', typeof new Set()); // object
其中typeof返回的类型都是字符串形式,需注意,例如:
1 2 |
|
typeof 缺点是只能判断基本数据类型和function类型(注意基本数据类型null返回的也是object),其他的数据类型比如数组和对象都返回obiect。
2、判断已知对象类型的方法: instanceof
console.log('测试 Number ->', 1 instanceof Number); // false
console.log('测试 Boolean ->', true instanceof Boolean); // false
console.log('测试 String ->', '' instanceof String); // false
// console.log('测试 null ->', null instanceof null);
// TypeError: Cannot read property 'constructor' of null
// console.log('测试 undefined ->', undefined instanceof undefined);
// TypeError: Cannot read property 'constructor' of undefined
console.log('测试 NaN ->', NaN instanceof Number); // false
console.log('测试 function ->', function () { } instanceof Function); // true
console.log('测试 Object ->', {} instanceof Object); // true
console.log('测试 Array ->', [] instanceof Array); // true
console.log('测试 Date ->', new Date() instanceof Date); // true
console.log('测试 Error ->', new Error() instanceof Error); // true
console.log('测试 RegExp ->', new RegExp() instanceof RegExp); // true
console.log('测试 Symbol ->', Symbol() instanceof Symbol); // false
console.log('测试 Map ->', new Map() instanceof Map); // true
console.log('测试 Set ->', new Set() instanceof Set); // true
console.log('测试 new Number ->', new Number(1) instanceof Number); // true
console.log('测试 new Boolean ->', new Boolean(true) instanceof Boolean); // true
console.log('测试 new String ->', new String('') instanceof String); // true
注意:instanceof 后面一定要是对象类型,并且大小写不能错,用来判断两个对象是否属于实例关系,该方法适合一些条件选择或分支。
instanceof的实现原理:获取目标类型的显式原型prototype以及需要判断的实例的隐式原型__proto__,将实例按原型链一级一级判断,直到__proto__为null,代表已经到Object顶层对象,此时返回false;若中途两者相等,则返回true。
3、根据对象的constructor判断: constructor
console.log('测试 Number ->', (1).constructor === Number); // true
console.log('测试 Boolean ->', true.constructor === Boolean); // true
console.log('测试 String ->', ''.constructor === String); // true
// console.log('测试 null ->', null.constructor === null);
// TypeError: Cannot read property 'constructor' of null
// console.log('测试 undefined ->', undefined.constructor);
// TypeError: Cannot read property 'constructor' of undefined
console.log('测试 NaN ->', NaN.constructor === Number);
// true 注意:NaN和infinity一样是Number类型的一个特殊值
console.log('测试 function ->', function () { }.constructor === Function); // true
console.log('测试 Object ->', {}.constructor === Object); // true
console.log('测试 Array ->', [].constructor === Array); // true
console.log('测试 Date ->', new Date().constructor === Date); // true
console.log('测试 Error ->', new Error().constructor === Error); // true
console.log('测试 RegExp ->', new RegExp().constructor === RegExp); // true
console.log('测试 Symbol ->', Symbol().constructor === Symbol); // true
console.log('测试 Map ->', new Map().constructor === Map); // true
console.log('测试 Set ->', new Set().constructor === Set); // true
注意: constructor 在类继承时会出错,不能判断null,undefined,其它的都可以。
4、通用但很繁琐的方法: Object.prototype.toString.call()
console.log('测试 Number ->', Object.prototype.toString.call(1)); // [object Number]
console.log('测试 Boolean ->', Object.prototype.toString.call(true)); // [object Boolean]
console.log('测试 String ->', Object.prototype.toString.call('')); // [object String]
console.log('测试 null ->', Object.prototype.toString.call(null)); // [object Null]
console.log('测试 undefined ->', Object.prototype.toString.call(undefined)); // [object Undefined]
console.log('测试 NaN ->', Object.prototype.toString.call(NaN)); // [object Number]
console.log('测试 function ->', Object.prototype.toString.call(function () { })); // [object Function]
console.log('测试 Object ->', Object.prototype.toString.call({})); // [object Object]
console.log('测试 Array ->', Object.prototype.toString.call([])); // [object Array]
console.log('测试 Date ->', Object.prototype.toString.call(new Date())); // [object Date]
console.log('测试 Error ->', Object.prototype.toString.call(new Error())); // [object Error]
console.log('测试 RegExp ->', Object.prototype.toString.call(new RegExp())); // [object RegExp]
console.log('测试 Symbol ->', Object.prototype.toString.call(Symbol())); // [object Symbol]
console.log('测试 Map ->', Object.prototype.toString.call(new Map())); // [object Map]
console.log('测试 Set ->', Object.prototype.toString.call(new Set())); // [object Set]
大小写不能写错,所有的数据类型都可以进行判断。
扩展:Object.prototype.toString.call()的原理