来一个基础他妈给基础开门-基础到家的知识-js的数据类型,没有任何其他答案了,这里的答案是唯一的,请往下看
| 序号 | 原始类型(基本类型) | typeof |
|---|---|---|
| 1 | Number | number |
| 2 | Boolean | boolean |
| 3 | String | string |
| 4 | BigInt(ES11+) | bigint |
| 5 | Symbol(ES6+) | symbol |
| 6 | Undefined | undefined |
| 7 | Null | object |
| 序号 | 对象类型(复杂类型) | typeof |
|---|---|---|
| 8 | Object | object/function |
有同学可能会说,不对啊 数组,函数呢??
简单说:数组只是作为 Object 的特殊变体,并不是独立的基本类型,注意,这是官方严格定义的,只有这8种。
typeof结果对应问题
如上面表里展示的,这是js里面比较烦人的地方,为什么呢?他不对应。 虽然说大部分都是对应的,但是涉及到 null,和 object 时问题就来了。
一. typeof null === 'object'
如果有人问你为什么会这样呢?你可以明确告诉他:“这是js作者留下的坑”,没错,这是js作者亲自承认的设计缺陷。
核心原因:JavaScript 32 位存储的类型标记位冲突
JavaScript 最初在实现时,采用 32 位二进制值 来存储所有数据类型,这个 32 位值分为两部分:
- 前 3 位(类型标记位) :用于标识数据的基础类型;
- 后 29 位:用于存储数据的实际值或内存地址。
当时规定了各类数据类型的标记位:
000:标记为 对象(object) ,后 29 位存储对象在内存中的地址;001:标记为字符串;010:标记为数字;100:标记为布尔值;110:标记为 undefined;
而 null 被设计为 表示 “空指针” (对应 C 语言中的 NULL 指针),在底层存储时,null 的 32 位二进制值被全部设为 000000...000。此时:
- 它的前 3 位标记位是
000,恰好与 对象(object) 的类型标记位完全一致; - 当
typeof运算符检测null时,会根据前 3 位标记位判断类型,最终返回object,这就是该问题的本质。 - 为什么不修复? 因为为了保证向后兼容,避免破坏现有代码生态,只能维持现有设计了;
二. typeof Object === 'object/function'
这里的Object表示的 对象类型 也有说是 引用类型 或者 复杂类型。包含数组(Array)、函数(Function)、日期(Date)、正则(RegExp)等子类型。
知识点来了,typeof 函数 结果是 function ,这个我们都知道函数也是对象的一种。那 函数对象 和 普通对象 的区别呢?
{
[[call]]
[[construct]]
}
如上图所示,函数对象里包含两个内部方法一个是 [[call]] 一个是 [[construct]]
JavaScript 中,对象是否为 “函数对象” 的核心标识是:该对象是否拥有内置的 [[Call]] 内部方法(这是一个不可直接访问的内部属性,仅引擎可识别) 。
[[Construct]]的核心作用:支持对象被new运算符调用,用于创建并返回新实例对象;- 存在性:普通函数 / 类 / 内置构造函数拥有
[[Construct]],箭头函数 / 内置工具函数无此方法; [[Call]]方法的作用:允许对象被作为函数调用(即通过()运算符执行,如fn());- 只有函数对象(包括普通函数、箭头函数、构造函数、类等)才会拥有
[[Call]]内部方法; - 普通对象(
{})、数组([])、日期(new Date())等均无[[Call]]方法。
typeof 运算符在检测时,会内部判断目标对象是否存在 [[Call]] 方法:
- 若存在(函数对象):直接返回
function;
总结
其实就是我觉的好像没啥要总结的。。。。。。