这段代码中发生了什么,Number 对象持有属性并递增数字?

问题描述

在这里。在 Stack Overflow 上看到这个很有趣 :)

在逐步完成行为之前,澄清一些事情很重要:

  1. 数字值数字对象a = 3vs a = new Number(3))非常不同。一个是原始的,另一个是对象。您不能将属性分配给基元,但可以分配给对象。

  2. 两者之间的强制是隐含的。

例如:

    (new Number(3) === 3)  // returns false
(new Number(3) == 3)   // returns true, as the '==' operator coerces
(+new Number(3) === 3) // returns true, as the '+' operator coerces
  1. 每个表达式都有一个返回值。当REPL读取并执行一个表达式时,这就是它显示内容。返回值通常并不代表您的想法,而是暗示不正确的事情。

好的,我们开始吧。

JavaScript 代码的原始图像

誓言。

> function dis() { return this }
undefined
> five = dis.call(5)
[Number: 5]

定义一个函数dis. 5这将5作为上下文 ( this) 执行函数在这里,它被从 Number 值强制转换为 Number 对象。需要注意的是,如果我们处于严格模式, ,这一点非常重要。

> five.wtf = 'potato'
'potato'
> five.wtf
'potato'

现在我们将属性设置five.wtf'potato',并以五个作为对象,果然它接受了Simple Assignment

> five * 5
25
> five.wtf
'potato'

作为five一个对象,我确保它仍然可以执行简单的算术运算。它可以。它的属性是否仍然存在?是的。

轮到。

> five++
5
> five.wtf
undefined

现在我们检查five++. 后缀增量的技巧是整个表达式将根据原始值进行评估 ,然后 增加该值。看起来five仍然是 5,但实际上表达式评估为 5,然后设置five6

不仅five被设置为6,而且还被强制转换回 Number 值,并且所有属性都丢失了。由于原语不能保存属性five.wtf因此未定义。

> five.wtf = 'potato?'
'potato?'
> five.wtf
undefined

我再次尝试将属性重新分配wtffive. 返回值暗示它粘住了,但实际上它并没有,因为five它是一个 Number 值,而不是一个 Number 对象。该表达式的计算结果为'potato?',但是当我们检查时,我们发现它没有被赋值。

声望。

> five
6

自从后缀增量以来,five一直是6.

解决方法

最近的一条推文包含这段
JavaScript。

有人可以逐步解释其中发生的事情吗?

> function dis() { return this }
undefined
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
> five * 5
25
> five.wtf
"potato"
> five++
5
> five.wtf
undefined
> five.wtf = 'potato?'
"potato?"
> five.wtf
undefined
> five
6

特别是,我不清楚:

  • 为什么 a 的结果dis.call(5)具有Number某种[[PrimitiveValue]]属性,但five++and的结果five * 5似乎只是普通数字525(而不是Numbers)
  • 为什么属性在增量five.wtf后消失five++
  • 尽管赋值显然设置了值,但为什么在增量five.wtf之后该属性甚至不再可设置。five++``five.wtf = 'potato?'