在 JS 中,为什么我可以使用像 toFixed() 这样的函数,它驻留在基本类型的 Number 包装对象的原型中?

In JS, why am I able to use functions like toFixed() which resides in the prototype of the Number wrapper object on a primitive type?

在JavaScript中,原始类型(数字、字符串等)不是对象。因此,他们没有 [[prototype]],因此无法使用某些对象的 [[prototype]] 中可用的方法。

而 Number、String 是包装对象,可用于通过 new 关键字创建变量,我们可以在这些变量上使用 Number 对象原型中可用的方法(使用 new关键字)。

但是在给定的代码中,我创建了一个原始类型变量并且能够使用像 toFixed() 这样驻留在数字对象中的方法。

这让我很困惑。请详细说明。

let a = 6.678; //primitive type

a= a.toFixed(1); // toFixed() resides in prototype of Number Object

console.log(a); // 6.7

这就是 JavaScript 引擎或多或少的工作原理。您分配给 a 的变量是 Number 类型的原语是正确的,但是当您访问此原语值的方法时,JS 将创建一个特殊的包装对象(它将为每个原语执行此操作类型,即字符串)并允许它访问这些方法。

访问该方法后,该值将不再是对象。

您可以在此处阅读更多相关信息: https://javascript.info/primitives-methods#a-primitive-as-an-object

@ashu 在下面的回答中包含了我实际上并不知道的技术术语 - 所以直到!显然,这就是所谓的“自动装箱”!

这与一个叫做“自动装箱”的概念有关,Javascript 看到您正在尝试访问原始类型的 属性,因此只有很短的时间运行时,它将原始值转换为其相应的 Wrapper 对象并继续 属性 调用,然后在大多数情况下将值转换回原始类型。

let a = 6.678; //primitive type

a= a.toFixed(1); // JS converts a to "Number Object" and then the function is called

console.log(a); // 6.7

这里有一个很好的答案Does javascript autobox?

由于 thisNumberValue 抽象操作,我们能够执行 toFixed() 操作,它检查 Type(value) 是 Number return 如果 Type(value) 是 Object 并且 value 有一个 [[NumberData]] 内部插槽,然后让 n 为值并分配 Type[n] 为 Number。 Return else 值抛出 TypeError 异常。

根据 ECMAScript® 2020 Language Specification

Number.prototype.toFixed (分数位数)

toFixed returns 包含此数值的字符串,以十进制定点表示法表示,小数点后有 fractionDigits 位数字。如果 fractionDigits 是 undefined,则假定为 0。

执行toFixed()操作时执行以下步骤:

  1. 让 x 是? thisNumberValue(this value).

注意 抽象操作 thisNumberValue(value) 执行以下步骤:

  • 如果 Type(value) 是数字,return 值。

  • 如果 Type(value) 是 Object 并且 value 有一个 [[NumberData]] 内部 插槽,然后

    • 设 n 为值。[[NumberData]].
    • 断言:Type(n) 是数字。
    • Return n.
  • 抛出 TypeError 异常。

  1. 让 f 是? ToInteger(fractionDigits)

    注意 抽象操作 ToInteger 将参数转换为整数值。这个抽象操作的作用如下:
  • 让数字是? ToNumber(argument)。 (注意ToNumber也是抽象操作)
  • 如果数字是 NaN,return +0。
  • 如果数字是+0、-0、+∞或-∞,return个数字。
  • Return数值 它与数字同号,其大小为 地板(绝对值(数字))。
  1. 断言:如果fractionDigits未定义,则f为0。