typeof
的八种数据类型
typeof
可判断类型比较有限,它的输出值只有八种,即用 typeof
判断一个变量,得到的结果只会是以下八种类型中的一种
// es5
typeof '' // string
typeof 1 // number
typeof true // boolean
typeof undefined // undefined
typeof Array // function
typeof {} // object
// es6
typeof Symbol() // symbol
// es10
typeof BigInt(1) // bigint
typeof
的实现原理
第一版 JS
的 typeof
实现如下,在 JS
诞生之初就只有六种类型判断。
if (JSVAL_IS_VOID(v)) { // 判断是否为 undefined
type = JSTYPE_VOID;
} else if (JSVAL_IS_OBJECT(v)) { // 判断是否为 object
obj = JSVAL_TO_OBJECT(v);
if (obj && (ops = obj->map->ops, ops == &js_ObjectOps)
? (clasp = OBJ_GET_CLASS(cx, obj), clasp->call || clasp == &js_FunctionClass)
: ops->call != 0) {
type = JSTYPE_FUNCTION;
} else {
type = JSTYPE_OBJECT;
}
} else if (JSVAL_IS_NUMBER(v)) { // 判断是否为 number
type = JSTYPE_NUMBER;
} else if (JSVAL_IS_STRING(v)) { // 判断是否为 string
type = JSTYPE_STRING;
} else if (JSVAL_IS_BOOLEAN(v)) { // 判断是否为 boolean
type = JSTYPE_BOOLEAN;
}
数组的判断
typeof
的输出值中没有 array
这一项,所以当需要判断数组类型时,可以使用 instanceof
。instanceof
会判断右侧表达式是否在左侧表达式的原型链上,所以下面的两个 instanceof
都为 true
。
typeof [1,2] // object
[1,2] instanceof Array // true
[1,2] instanceof Object // true
独树一帜的 null
可以用 typeof
判断 null
类型嘛?
答案是 NO
,前面说了,typeof
只有八种类型,其中并没有 null
这一类型,如果用 typeof
判断,会得到 object
的结果。
typeof null // object
为什么?
因为在 Javascript
底层存储变量的时候,会在变量的机器码低位 1-3
位表示类型信息。而 null
的低位 1-3
解析到的为 000
,而000
表示的是 obecjt
类型。
000 对象
010 浮点数
100 字符串
110 布尔值
1 整数
null:所有码都是0
undefined:用 -2^30 表示
可以用 instanceof
判断 null
类型嘛?
答案依然是 NO
,因为 null
根本没有 __proto__
属性,所以用 instanceof
去检测永远都不会返回 true
null instanceof Object // false
null instanceof null // 报错
那要怎么判断?
- 强等,最简单的判断方式
===
判断是否是null
- 通过
Object.prototype.toString
判断
null === null // true
Object.prototype.toString.call(null) // [object Null]
拓展:Object.prototype.toString
可以判断所有类型
Object.prototype.toString.call(1) // [object Number]
Object.prototype.toString.call('') // [object String]
Object.prototype.toString.call({}) // [object Object]
Object.prototype.toString.call(true) // [object Boolean]
Object.prototype.toString.call(()=>{}) // [object Function]
Object.prototype.toString.call(null) // [object Null]
Object.prototype.toString.call(undefined) // [object Undefined]
Object.prototype.toString.call(Symbol) // [object Symbol]
Object.prototype.toString.call(1n) // [object BigInt]
instanceof
实现原理
function new_instance_of(leftValue, rightValue) {
let rightProto = rightValue.prototype;
leftValue = leftValue.__proto__;
while(true) {
if (leftValue === null) {
return false;
}
if (leftValue === rightProto) {
return true;
}
leftValue = leftValue.__proto__
}
}
课后习题
下面的表达式分别输出什么呢?如果全部回答正确,你对原型链和 instanceof
的理解应该非常到位了。
Object instanceof Object
Function instanceof Function
Function instanceof Object
Object instanceof Function