js 数据类型的判断

133 阅读1分钟

基本数据类型有8种: Undefined 、 Null 、 Boolean 、 Number 、 String 、 Object 、 Symbol 、 BigInt

  • Symbol 代表独一无二的值,常用来定义对象的唯一属性名。
  • BigInt 可以表示任意大小的整数。

第一种方式:typeof

缺陷:对数组、null 判断的不精准,返回的是 object。

console.log(typeof undefined); // undefined
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof "str"); // string
console.log(typeof Symbol("foo")); // symbol
console.log(typeof 2172141653n); // bigint
console.log(typeof function () { }); // function

// 不能判别
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object

第二种方式:instanceof

原理:检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

优点:可以准确的判断出数组等引用数据类型

class People { }
class Student extends People { }

const vortesnail = new Student();

console.log(vortesnail instanceof People); // true
console.log(vortesnail instanceof Student); // true
console.log(9 instanceof Number); // false
console.log(true instanceof Boolean); // false 
console.log('libo' instanceof String); // false  
console.log([] instanceof Array); // true
console.log(function () { } instanceof Function); // true
console.log({} instanceof Object); // true

第三种方式:constructor

注意:nullundefined 是无效的对象,所以他们不会有 constructor 属性

缺点:如果有同事重写了 prototype,原有的 constructor 引用会丢失,默认为 Object

(1).constructor === Number //true

true.constructor === Boolean //true

"".constructor === String //true

(function () { }).constructor === Function //true

[].constructor === Array //true

({}).constructor === Object //true

终极大招:Object.prototype.toString.call(obj)

优点:不用担心被别人篡改prototype挖坑了

Object.prototype.toString.call('') ;              // [object String]
Object.prototype.toString.call(1) ;               // [object Number]
Object.prototype.toString.call(true) ;            // [object Boolean]
Object.prototype.toString.call(Symbol());         // [object Symbol]
Object.prototype.toString.call(undefined) ;       // [object Undefined]
Object.prototype.toString.call(null) ;            // [object Null]
Object.prototype.toString.call(new Function()) ;  // [object Function]
Object.prototype.toString.call(new Date()) ;      // [object Date]
Object.prototype.toString.call([]) ;              // [object Array]
Object.prototype.toString.call(new RegExp()) ;    // [object RegExp]
Object.prototype.toString.call(new Error()) ;     // [object Error]
Object.prototype.toString.call(document) ;        // [object HTMLDocument]
Object.prototype.toString.call(window) ;          // [object global] window 是全局对象 global 的引用

彩蛋

underscore 或者 lodash 里面的判断类型的方法是怎么设计的?

function tagTester(name) {
  var tag = "[object" + name + "]"
  return function (obj) {
    return toString.call(obj) === tag
  }
}
var isString = tagTester("String")
var isNumber = tagTester("Number")
var isDate = tagTester("Date")
var isRegExp = tagTester("RegExp")
var isFunction = tagTester("Function")
var isSymbol = tagTester("Symbol")
var isError = tagTester("Error")
var isArrayBuffer = tagTester("ArrayBuffer")