最近的一条推文 包含这段 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
特别是,我不清楚:
- why the result of
dis.call(5)
is aNumber
with some kind of a[[PrimitiveValue]]
property, but the results offive++
andfive * 5
似乎只是纯数字5
和25
(不是Number
s) - 为什么
five.wtf
属性在five++
增量后消失 - 为什么
five.wtf
属性在five++
增量之后甚至不再可设置,尽管five.wtf = 'potato?'
分配显然设置了值。
原文由 Nathan Long 发布,翻译遵循 CC BY-SA 4.0 许可协议
OP在这里。在 Stack Overflow 上看到这个很有趣 :)
在逐步执行该行为之前,澄清几件事很重要:
数字值 和 数字对象(
a = 3
vsa = new Number(3)
)非常不同。一个是原语,另一个是对象。您不能将属性分配给基元,但可以分配给对象。两者之间的强制是隐含的。
例如:
好的,我们开始吧。
誓言。
定义一个函数
dis
并用5
调用 它。这将以5
作为上下文(this
)执行函数。这里它从一个数字值被强制转换为一个数字对象。非常重要的是要注意,如果我们处于 严格模式 ,就不会发生这种情况。现在我们将属性
five.wtf
设置为'potato'
,并以 5 作为对象,果然它接受了 Simple Assignment 。以
five
作为对象,我确保它仍然可以执行简单的算术运算。它可以。它的属性仍然存在吗?是的。轮到。
现在我们检查
five++
。 后缀递增 的技巧是整个表达式将根据原始值求值 ,然后 递增该值。它看起来像five
仍然是五,但实际上表达式评估为五,然后设置five
到6
。不仅
five
被设置为6
,而且它被强制变回数字值,并且所有属性都丢失了。由于基元不能保存属性,five.wtf
未定义。我再次尝试将属性
wtf
重新分配给five
。返回值暗示它会粘住,但实际上不会,因为five
是一个数字值,而不是一个数字对象。该表达式的计算结果为'potato?'
,但是当我们检查时我们发现它没有被分配。声望。
自从后缀增量以来,
five
一直是6
。