在 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
null
和undefined
不存在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]"