一、前导知识
javascript中的内置数据类型有以下几大类
ES5中类型
/* 基本数据类型 */
字符串: string
数字:number
布尔值:boolean
/* 特殊值 */
未定义: undefined
空值: null
/* 复合类型 */
对象:object(Array, Function, {}, RegExp)
后期新增
- symbol(ES6新增)
- BigInt(ES2020)
二、typeof 原理
除对象类型其他的都称为“基本类型”,typeof的返回值为各自的类型值。由于历史原因,typeof null返回object,typeof function,返回function。后面会介绍。
/**
* typeof实例
*/
console.log("---- basic type ----");
console.log("typeof '123' -> " + typeof '123');
console.log("typeof 123 -> " + typeof 123);
console.log("typeof true -> " + typeof true);
console.log("typeof null -> " + typeof null);
console.log("typeof undefined -> " + typeof undefined);
console.log("---- object ----");
console.log("typeof {} -> " + typeof {});
console.log("typeof function(){} -> " + typeof function (){});
console.log("typeof [] -> " + typeof []);
console.log("typeof /reg/ig -> " + typeof /reg/ig);
console.log("---- 新类型 ----");
console.log("typeof Symbol() -> " + typeof Symbol());
console.log("typeof 123n -> " + typeof 123n);
结果如下
---- basic type ----
typeof '123' -> string
typeof 123 -> number
typeof true -> boolean
typeof null -> object
typeof undefined -> undefined
---- object ----
typeof {} -> object
typeof function(){} -> function
typeof [] -> object
typeof /reg/ig -> object
---- 新类型 ----
typeof Symbol() -> symbol
typeof 123n -> bigint
函数对象包含[[call]]
,函数也被称为可执行对象
。
所有typeof为object的对象都包含内部属性[[class]]
,可以通过Object.prototype.toString(...)
来查看这个值。
/**
* Object内部分类[[class]] 示例
*/
console.log("---- [[class]] ----");
console.log("Object.prototype.toString.call({}) -> " + Object.prototype.toString.call({}));
console.log("Object.prototype.toString.call([]) -> " + Object.prototype.toString.call([]));
console.log("Object.prototype.toString.call(function(){}) -> "
+ Object.prototype.toString.call(function (){}));
console.log("Object.prototype.toString.call(/reg/ig) -> " + Object.prototype.toString.call(/reg/ig));
// 输出内容如下
// ---- [[class]] ----
// Object.prototype.toString.call({})[object Object]
// Object.prototype.toString.call([])[object Array]
// Object.prototype.toString.call(function(){})[object Function]
// Object.prototype.toString.call(/reg/ig) -> [object RegExp]
typeof 和 instanceof 都是运算符,不是函数。
检测机制
不同的数据类型在JS底层表示的二进制数据不一样。主要区分在低三位
(右侧数据)。在第一版的js设计中,使用32位作为存储单元,并使用低三位(1-3位)表示值的类型(参考文献)
- 000:Object类型,后续位数用于存储指向对象的引用。而null的后31位全是0,用于表示无引用,也就是空对象。
- 1:int类型,后续位数存储一个31位的有符号整数。
- 010:double类型。后续位数存储一个双精度浮点数。
- 100:string类型。
- 110:布尔值
这也就是解释了前面提到的typeof null -> object
问题
三、instanceof 原理
instanceof示例
/**
* instanceof示例
* VM instanceof Constructor
*/
console.log("[] instanceof Array -> " + ([] instanceof Array)); // true
console.log("[] instanceof Object -> " + ([] instanceof Object)); // true
console.log("[] instanceof RegExp -> " + ([] instanceof RegExp)); // false
instanceof是通过原型链检测,检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。instanceof 可以检测某个实例是否为某个构造函数的实例。可以越级检测(父类、父父类)。
instanceof 只适用于对象类型的检测