使用“in”运算符搜索toFixed - “in”运算符在原始类型上如何工作?

3

我开始无聊地阅读YDKJS,发现他写道:

我们可以做类似这样的事情:

var num = (1.2).toFixed(1)

所以 - 这意味着toFixed被作为整数值的成员方法调用。

那么为什么这不起作用??

"toFixed" in 1.222

但是这个有效:

"toFixed" in new Number(1.222)

7
"1.222"是一个原始值 - 它没有任何方法。当你调用(1.2).toFixed(1)时,它会被转换为一个Number对象。 - VLAZ
这是显式强制转换吗? - Probosckie
隐式转换可能有点可疑。(1.2).toFixed(1) 几乎 等同于 new Number(1.2).toFixed(),但你实际上可能得不到一个真正的对象,环境可能会表现得好像你这样做了,但并没有创建、丢弃和垃圾回收一个对象。 - VLAZ
@vlaz 引擎所采取的优化步骤与规范无关。它们将完全按照那样的方式运行,引擎可能会在两种情况下优化构造函数(或者可能不会,谁知道...)。 - Jonas Wilms
如果有人想在规范中查找隐式强制转换,可以查看被GetValue调用的7.1.13 ToObject - Jonas Wilms
显示剩余2条评论
1个回答

2
Es262规范的第268页指出:
RelationalExpression:RelationalExpression in ShiftExpression
...
让rref成为评估ShiftExpression的结果。
让rval成为? GetValue(rref)。
如果Type(rval)不是Object,则抛出TypeError异常。
换句话说,您不能在数字上使用in。这就是它的定义方式。
但是,new Number不会创建数字,而是创建一个数字对象(从Number.prototype继承的对象)。这就是为什么您可以在它上面使用in的原因,因为它是一个实际的对象。
你仍然可以做12..toFixed(),这是因为规范中有一个非常有趣的结构:抽象的GetValue操作(当您访问属性¹时调用),如果目标(在这种情况下为12)不是对象,则调用toObject,然后将执行以下操作:
返回一个新的Number对象,其[[NumberData]]内部槽设置为参数。
换句话说,12..toFixed()与new Number(12).toFixed()完全相同。
¹有趣的是,根据规范,访问属性本身实际上并没有这样做,如果您执行a.b,那只会查找a的值并创建一个引用(Reference(a,“b”))。当在其上调用GetValue时,实际的属性查找发生(但是我不知道是否有任何情况下Reference会丢失而不调用GetValue)。

你仍然可以执行12..toFixed(),这很好,但是OP问的是浮点数,例如1.31.2。那么我们该怎么做呢? - weegee
1
@weegee,JS 中并不存在所谓的“floats”。它们只是数字。 - Jonas Wilms
我知道,但我使用这个词来表示十进制值。 - weegee
@weegee 我不明白你的意思。12..toFixed()1.2.toFixed()之间没有技术上的区别。 - Jonas Wilms
1
@weegee 在JS中,所有数字原始类型都表示为IEEE 754浮点数。无论是-2还是0.5,它们都有一个符号、尾数和指数,按照相同的标准用二进制表示。除了这三个组成部分的值不同之外,这两个数字之间没有任何区别 - 对任何原始数字执行的任何操作都将使用与任何其他数字相同的机制解决。 - VLAZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接