# 类型判断(上)

类型判断在日常开发中非常有必要。

# 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:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be the result of calling ToObject passing the this value as the argument.
  4. Let class be the value of the [[Class]] internal property of O.
  5. 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
};
上次更新: 1/22/2025, 9:39:13 AM