# ES6中的数据类型判断的几种方式
# 1.typeof
typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型,返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:
- number、
- boolean、
- symbol、
- string、
- object、
- undefined、
- function 等。
1 | typeof ''; // string 有效 |
总结:
- 对于基本类型,除 null 以外,均可以返回正确的结果。
- 对于引用类型,除 function 以外,一律返回 object 类型。
- 对于 null ,返回 object 类型。
- 对于 function 返回 function 类型。
# 2.instanceof
- instanceof 检测的是原型对象。
- instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B。
- 如果 A 是 B 的实例,则返回 true,否则返回 false。
- 当 A 的 proto 指向 B 的 prototype 时,就认为 A 就是 B 的实例
1 | [] instanceof Array; // true |
原型链举例
1 | [].__proto__ --> Array.prototype |
问题总结:
- instanceof 只能用来判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型。
- 它假定只有一个全局执行环境。如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的构造函数。
1 | var iframe = document.createElement('iframe'); |
- ES5 提供了 Array.isArray() 方法 。该方法用以确认某个对象本身是否为 Array 类型,而不区分该对象在哪个环境中创建。
1 | if (Array.isArray(value)){ |
Array.isArray() 本质上检测的是对象的 [[Class]] 值,[[Class]] 是对象的一个内部属性,里面包含了对象的类型信息,其格式为 [object Xxx] ,Xxx 就是对应的具体类型 。对于数组而言,[[Class]] 的值就是 [object Array] 。
# 3.constructor
- 当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向 F 的引用
- 当执行 var f = new F() 时,F 被当成了构造函数,f 是F的实例对象,此时 F 原型上的 constructor 传递到了 f 上,因此 f.constructor == F
- F 利用原型对象上的 constructor 引用了自身,当 F 作为构造函数来创建对象时,原型上的 constructor 就被遗传到了新创建的对象上, 从原型链角度讲,构造函数 F 就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型。
注意:
- null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
- 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
# 4.toString
- toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
- 对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
1 | Object.prototype.toString.call('') ; // [object String] |
# 总结
typeof:
- 可判断
- 数值
- 字符串
- 布尔值
- undefined
- function
- 不可判断
- null
- object
- array
instance:
- 判断对象具体类型
全等于:
- null/undefined