《JavaScript 高级程序设计(第 4 版)》和各个大佬的文章所归纳的总结,如有异议按你的理解为主
JavaScript 中的数据类型分为基本数据类型和引用数据类型
注: 基本数据类型也可以叫原始数据类型
在 ES2020 标准下的 JavaScript 一共有以下 7 种基本类型
undefined 未定义null 空指针boolean 布尔值string 字符串number 数值symbol 独一无二的值 (ES6 引入)bigint 大整数 (ES2020 引入)ECMAScript 提供了 3 种特殊的引用类型:Boolean Number String,每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,在执行完后再销毁这个包装对象
在 JavaScript 中除了基本类型,其他的都是引用类型,常见的引用类型如下
Object 对象Array 数组Function 函数Date 日期与时间RegExp 正则表达式Set 类似于数组但成员的值都是唯一的 (ES6 引入)WeakSet (ES6 引入)Map 类似于对象也是键值对的集合 (ES6 引入)WeakMap (ES6 引入)JavaScript 不允许直接访问内存位置(不能直接操作对象所在的内存空间),所以引用类型在 栈内存 中存储的是地址(内存指针),而引用类型中的数据(方法或属性)是存储在 堆内存 中常见的五种判断方式
typeofinstanceofconstructorArray.isArray()Object.prototype.toStringnull 外的基本类型都能准确判断JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此null 的类型标签是 0,typeof null 也因此返回 "object" —— MDN
function 外的引用类型均返回 objectinstanceof 用于检测构造函数的 prototype 属性是否存在于实例对象的原型链上
instanceof 不能判断基本类型,对于引用类型只能判断原型链上的从属关系instanceof 并不完全可靠,因为构造函数的 prototype 属性可能会被修改
ES6 提供的 Reflect.setPrototypeOf() 方法__proto__ 伪属性实例对象可以通过 constructor 属性去访问它的构造函数
constructor 可以判断除 undefined 和 null 外的所有基本类型和引用类型(undefined 和 null 不存在构造函数)constructor 并不完全可靠,因为构造函数的 prototype 属性可能会被修改,从而造成 constructor 属性指向不准确Array.isArray() 用于判断一个值是否是数组 (Array)
toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用,默认情况下 toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖 toString() 返回 "[object type]" 其中 type 是对象的类型Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用toString 方法的在 ECMAScript 5 下的大致执行过程
this 是 undefined 返回 [object Undefined]this 是 null 返回 [object Null]O 成为 ToObject(this) 的结果class 成为 O 的内部属性 [[Class]] 的值"[object " class "]" 三个部分组成的字符串不同 ECMAScript 版本对 toString 方法的规范都有所不同