# 类型判断(上)
类型判断在日常开发中非常有必要。
# 1、typeof
typeof
我们一般作为运算符使用
typeof 是一元操作符,放在其单个操作数的前面,操作数可以是任意类型。返回值为表示操作数类型的一个字符串。
下面这6中数据类型根据typeof的返回值不是一一对应的
Undefined, Null, Boolean, Number, String, Object
返回的结果分别如下, 其中Null和Object都返回了字符串object
。
typeof undefiend; // 'undefined'
typeof null; // 'object'
typeof true; // 'boolean'
typeof 1; // 'number'
typeof 'str'; // 'string'
typeof {}; // 'object'
总结就是typeof可以检测出6种类型的值, 但是面对Array, Function, RegExp, Date, Error 等都返回object
typeof [] // 'object'
typeof /[0-9]/ // 'object'
typeof new Date() // 'object'
# 2、Object.prototype.toString
Object.prototype.toString
可以精准的判断各个类型。
When the toString method is called, the following steps are taken:
- If the this value is undefined, return "[object Undefined]".
- If the this value is null, return "[object Null]".
- Let O be the result of calling ToObject passing the this value as the argument.
- Let class be the value of the [[Class]] internal property of O.
- Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
返回结果如下
var number = 1; // [object Number]
var string = '123'; // [object String]
var boolean = true; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {a: 1} // [object Object]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a(){}; // [object Function]
function checkType() {
for (var i = 0; i < arguments.length; i++) {
console.log(Object.prototype.toString.call(arguments[i]))
}
}
checkType(number, string, boolean, und, nul, obj, array, date, error, reg, func)
console.log(Object.prototype.toString.call(Math)); // [object Math]
console.log(Object.prototype.toString.call(JSON)); // [object JSON]
function a() {
console.log(Object.prototype.toString.call(arguments)); // [object Arguments]
}
a();
WARNING
需要注意的是 Object.prototype.toString.call(NaN) === '[object Number]'
返回true
# 3、EmptyObject
是否是一个没有属性的空对象
function isEmptyObject(obj) {
if (!obj) return false;
if (isObject(obj)) {
return Object.keys(obj).length === 0;
}
return false;
}
# 4、封装判断函数
const class2type = {};
// 生成class2type映射
'Boolean Number String Function Array Date RegExp Object Error'
.split(' ')
.map(function (item, index) {
class2type['[object ' + item + ']'] = item.toLowerCase();
});
function type(obj) {
// if (obj == null) {
if (obj === null || obj === undefined) {
return obj + '';
}
return typeof obj === 'object' || typeof obj === 'function'
? class2type[Object.prototype.toString.call(obj)] || 'object'
: typeof obj;
}
function isBoolean(obj) {
return type(obj) === 'boolean';
}
// 此处不认为NaN是一个数字
function isNumber(obj) {
if (type(obj) === 'number') {
if (Number.isNaN(obj)) {
return false;
}
return true;
}
return false;
}
function isString(obj) {
return type(obj) === 'string';
}
function isFunction(obj) {
return type(obj) === 'function';
}
const isArray =
Array.isArray ||
function (obj) {
return type(obj) === 'array';
};
function isDate(obj) {
return type(obj) === 'date';
}
function isRegExp(obj) {
return type(obj) === 'regexp';
}
function isObject(obj) {
return type(obj) === 'object';
}
function isError(obj) {
return type(obj) === 'error';
}
// 是否是一个没有属性的空对象
function isEmptyObject(obj) {
if (!obj) return false;
if (isObject(obj)) {
return Object.keys(obj).length === 0;
}
return false;
}
function isWindow(obj) {
return obj !== null && obj.window === obj;
}
// isElement 判断是不是 DOM 元素。
function isElement() {
return !!(obj && obj.nodeType === 1);
}
export {
isBoolean,
isNumber,
isString,
isFunction,
isArray,
isDate,
isRegExp,
isObject,
isError,
isEmptyObject,
isWindow,
isElement
};