JavaScript 判断数据类型方法

268 阅读2分钟

在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示:

基本类型:String、Number、Boolean、Symbol、Undefined、Null

引用类型:Object(Function 、Array、RegExp、Date...)

typeof

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
语法: typeof operand

typeof 1 === 'number' // true

typeof '2' === 'string' // true

typeof undefined === 'undefined' // true

typeof true === 'boolean' // true

typeof [1,2,3] === 'object' // true

typeof null // object

var fn = function(){}
typeof fn // function

typeof null

typeof null === 'object'

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"

使用 new 操作符

除 Function 外的所有构造函数的类型都是 'object'

var a = new Number(1)
ctypoef a // object

var b = new String('1')
typoef b // object

var c = new Function()
typoef c // function

instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
语法:object instanceof constructor

[] instanceof Array //true
{} instanceof Object //true

function D() {}
var d = new D()
d instanceof D //true
d instanceof Object //true
D.prototype instanceof Object //true

JavaScript 实现 instanceof

function customInstanceof(left, right) {
    const rightProto = right.prototype 
    const leftProto= left.__proto__
    while(true) {
      if(leftProto === null) {
        return false
      } else if (leftProto === rightProto) {
        return true
      }
      leftProto = leftProto.__proto__
    }
  }
      
  console.log(customInstanceof({}, Object)) //true

constructor

构造函数属于被实例化的特定类对象。构造函数初始化这个对象,并提供可以访问其私有信息的方法。

function E() {}
E.prototype // {constructor: ƒ}
var e = new E()
e.constructor == E

// 由此
var a = 1
a.constructor == Number // true
var b = '1'
b.constructor == String // true

nullundefined不存在constructor

var a = null
a.constructor // Cannot read property 'constructor' of null
var b = undefined
b.constructor // Cannot read property 'constructor' of null

函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

function F() {}
var f = new F()
f.constructor == F // true

F.prototype = {}
var f1 = new F()
f1.constructor == F // false
f1.constructor // ƒ Object() { [native code] }
F.constructor // ƒ Function() { [native code] }

F的 prototype 被赋值为{}{} 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 {},也就是 Object 本身。

使用 toString() 检测对象类型 (Object.prototype.toString)

可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg

Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(null) // "[object Null]"

(参考文章:www.cnblogs.com/onepixel/p/…