1. typeof
可以判断8种数据类型:
- 基本类型6个
undefined null boolean, number, string、symbol - 引用类型2个
object、function
注意点:
typeof null // 'object': 不能用typeof判断null,得用===判断typeof [] // 'object': 不能判断出来array和object,因为都是objecttypeof (() => {}) // 'function': 可以判断出来function
为什么这样设计,是不是js语言的糟粕,但是我们写代码的时候要注意这些,不然容易出bug。如果要判断Object类型的具体类型的话,就需要用Object.prototype.toString
2. Object.prototype.toString
判断方法Object.prototype.toString.call(xxx), 返回格式是[object xxx],xxx就是具体类型,可以取出来。
注意不能用obj.toString() 这个是类型转换为字符串的方法,都重写了这个方法,例如function类型返回函数体的字符串,array类型返回元素组成的字符串。所以判断类型需要调用Object原型链上的方法,并且要call调用。
var number = 1;
var string = '';
var boolean = true;
var und = undefined;
var nu = null;
var sym = Symbol('a');
var obj = {a: 1};
var array = [1, 2, 3];
var date = new Date();
var error = new Error();
var reg = /a/g;
var func = function a() {};
function checkType() {
for (var i = 0; i < arguments.length; i++) {
console.log(Object.prototype.toString.call(arguments[i]));
}
}
checkType(number, string, boolean, und, nu, sym, obj, array, date, error, reg, func);
结果:
可以结合以上两个写类型判断函数,如果是object就用Object.prototype.toString方法,否则用typeof。
function getToStringType(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
/**
* object、function用toString,其余用typeof
* @param {} obj
*/
function type(obj) {
return typeof obj === 'object' || typeof obj === 'function' ?
getToStringType(obj) || 'object' : typeof obj;
}
// 判断函数
function isFunction(obj) {
return type(obj) === 'function';
}
function isArray(obj) {
return type(obj) === 'array'
}
3. instanceof
判断引用类型,a instanceof B 是判断右侧函数的原型对象是否在左侧对象的原型链上,如果是返回true。
function myInstanceof(left, right) {
let leftProto = getPrototypeOf(left);
const rightPrototype = right.prototype;
while (leftProto) {
if (leftProto === rightPrototype) {
return true;
}
leftProto = getPrototypeOf(leftProto)
}
return false;
}
4. 判断数组的方式有哪些?
- Array.isArray()
- obj instanceof Array
- getToStringType(obj) === 'array'
- obj.proto === Array.prototype
5. null与undefined
- null:空对象;
- undefined: 为定义
看见这个结果就想maniang。
isNaN 与 Number.isNaN
- isNaN: 会尝试将参数转换为数值,任何不能转化为数值的值都会返回true,即非数字值传入也会返回true,有问题
- Number.isNaN: 会先判断是否是数字,如果是数字再判断是否是NaN,不会进行类型判断,所以对于NaN判断更准确。
[1, 2, 3, 4].map(parseInt);
// 1 NaN NaN NaN
parseInt传入0或者不传,按照字符串转为10进制