判断数据类型几种方式

460 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

好好学习,天天向上。

前言

我们在进行业务开发过程中,一定回避不了的一个问题,就是数据类型的判断。 今天我们就一起来聊聊常见的数据类型的判断。

typeof

typeof能判断出基本的数据类型, 返回值是字符串。
返回值有如下几种可能性:

  • 'undefined'
  • 'boolean'
  • 'string'
  • 'number'
  • 'symbol'
  • 'bigint'
  • 'function'
  • 'object'

不能判断更具体的对象类型, 所以一般是结合Object.prototype.toString使用。

constructor

构造函数,所以能判断具体的对象和函数

比如如下判断数组和函数,只是举个例子。

function isArray(arr){
    return !!(arr && arr.constructor === Array)
}

function isFunction(fn){
    return !!(fn && fn.constructor === Function)
}

但是注意了,构造函数可以改写,当然你也可以通过Object.freeze或者Object.defineProperty来设置其不可被修改。

再看看 redux的 [kindOf.js]
(github.com/reduxjs/red…)

     const constructorName = ctorName(val)
      switch (constructorName) {
        case 'Symbol':
        case 'Promise':
        case 'WeakMap':
        case 'WeakSet':
        case 'Map':
        case 'Set':
          return constructorName
        default:
          break
      }

instanceof

这个判断的原理就是原型链上查找,查到即是实例,当然原型链是另外一个话题了。

function isArray(arr){
    return !!(arr && arr instanceof Array)
}

再看看 redux的 kindOf.js的 isError方法

    function isError(val) {
      return (
        val instanceof Error ||
        (typeof val.message === 'string' &&
          val.constructor &&
          typeof val.constructor.stackTraceLimit === 'number')
      )
    }

isPrototypeOf

本质也是原型链判断。
fetch有一段DataView的代码:

function isDataView(obj) {
  return obj && DataView.prototype.isPrototypeOf(obj)
}

Object.prototype.toString

这个和typeof是最常用的判断数据类型的方法。

const toString = Array.prototype.toString
function isWindow(obj){
    return toString.call(obj) == "[object Window]"
}

鸭子类型检测

就是检查某些属性和方法存在不存在。

周下载量百万的的 p-is-promise

const isObject = value => value !== null &&
	(typeof value === 'object' || typeof value === 'function');

export default function isPromise(value) {
	return value instanceof Promise ||
		(
			isObject(value) &&
			typeof value.then === 'function' &&
			typeof value.catch === 'function'
		);
}

在Array.isArray方法出现以前,数组的检测也是鸭子类型检测。 主要是判断length和下标。

Symbol.toStringTag

这个是ES6+的提供的一种方式。

MDN描述:

Symbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签,通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。

window[Symbol.toStringTag] // Window
(new Set())[Symbol.toStringTag] // Set

等比较

当然就是直接比较,比如是不是window。

function isCurrentWindow(obj){
    return obj === window
}

比如 underscode对undefined的判断。

  // Is a given variable undefined?
  _.isUndefined = function(obj) {
    return obj === void 0;
  };

小结

今天你收获了吗?