javascript 是否存储原型之外的数据类型信息?

Does javascript store datatype information beyond the prototype?

我正在 Javascript 学习原型设计,并且为了实验,我试图尽可能地去除一些基本对象的信息。但是,我 运行 在以下代码段中遇到了问题:

let x = [];
Object.setPrototypeOf(x, null);
console.log(Object.prototype.toString.call(x));
>>> [object Array]

我这里的疑惑:去掉原型后,Object.prototype.toString怎么还知道xArray类型?如果不是任何属性,这些信息来自哪里? 运行 Object.getOwnPropertyNames(x)Object.getOwnPropertySymbols(x),我没有在 x 上看到任何包含字符串 Array 路径的属性。这些信息存储在哪里?

如果这是那些“内部插槽”之一(虽然我不确定它会是哪个),是否没有办法修改它?我至少可以直接访问它吗?

更新: Yousaf 注意到 属性 String.toStringTag 通常由 Object.prototype.toString 访问,以提供在上述示例中代替“Array”的字符串。实际上,设置 x[Symbol.toStringTag] = 'my_string' 允许我们更改 .toString() 值。然而,我认为它仍然没有解开谜团,因为 x[Symbol.toStringTag] 在我们设置它之前是 undefined,不包含所需的“Array”字符串。

当在任何对象上调用 .toString() 时,它会创建一个 [object x] 形式的字符串,其中 x 是 [=34] 的构造函数 in-case 的名称=] 构造函数,例如 DateArray.

调用 .toString() 时,需要执行多个步骤,其中一个步骤是检查 .toString()this 的值是否为数组。如果它是一个数组,则标签设置为字符串 'Array'.

来自Spec - 19.1.3.6 Object.prototype.toString ( )

  1. If isArray is true, let builtinTag be "Array".

在 ES6 之前,当在用户定义的构造函数的实例上调用 .toString() 时,会记录 [object Object]。 ES6 提供了一种使用 well-known 符号 Symbol.toStringTag.

覆盖标签的方法