参考文献

一、前导知识

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 只适用于对象类型的检测

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注