JavaScript使用++时出现奇怪的行为

5

大家都知道在JavaScript中如何使用基本的字符串拼接:

> "Hello " + "World!"
'Hello World!'

但是,如果我们使用 + + 而不是 + 会发生什么?我遇到了以下奇怪的行为:

> "Hello " + + "World!"
'Hello NaN'
> "Hello " + + ""
'Hello 0'

从上面的例子中,我可以看到第二个字符串被转换为数字。因此,如果传递一个具有 valueOf 属性作为函数的对象,则将转换为该函数返回的值。
> "Hello " + + ({valueOf: function () {return 1; }})
'Hello 1'

正如预期的那样,它显示"Hello 1"


第二个字符串为什么要转换成Number?为什么不抛出语法错误之类的东西呢?


@jeremyharris 是的,但不是 ++ (+ <空格> +)。 - Ionică Bizău
评估 + "" 会给你零 - Prabhu Murthy
完全明白:收到了,已删除 :) - jeremyharris
3个回答

3
第二个 +一元正号运算符,其目的是将其操作数转换为数字。
一元正号运算符位于其操作数之前,并将其评估为其操作数,但如果其操作数不是数字,则尝试将其转换为数字。虽然一元否定(-)也可以将非数字转换为数字,但一元正号是将某些东西转换为数字的最快且首选方法,因为它不执行任何其他操作。它可以将整数和浮点数的字符串表示形式以及true、false和null等非字符串值转换为数字。十进制和十六进制(“0x”前缀)格式中的整数都受支持。支持负数(但对于十六进制不支持)。如果无法解析特定值,则将计算为NaN。
"Hello " + + "World!"

只能被解析为

"Hello " + (+ "World!")

这是

"Hello " + NaN

因此,这是您的结果。
这个一元运算符在JavaScript中非常有用,是将可能是数字或字符串的内容转换为数字的最常见方法之一。与parseFloat相比,它的优点在于它不是过度宽容的(parseFloat(“7up”)会返回7),这使得它成为一种简单的方法来判断一个字符串是否是数字的表示形式(只需测试s==+s)。

确实,你能解释一下为什么这不是语法错误吗? - Ionică Bizău
为什么会是语法错误?+ somestring 是完全有效的(请参见我链接到的文档) - Denys Séguret
有道理。谢谢! - Ionică Bizău

2
很好的问题。这是因为JavaScript有一个一元的+运算符(类似于一元的-,例如-1,它被解析为-(1)):https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus_(.2B) 因此,"foo" + + "bar"被解析为"foo" + (+ "bar")(或者如果你喜欢Lisp风格的解析树:(+ "foo" (+ "bar"))。
一元的+将其操作数转换为数字,如果操作数不是合理的数字,则返回NaN
> +"42"
42
> +"foo"
NaN

最后,将数字(包括 NaN)添加到字符串中会导致字符串连接。

因此,"foo" + +"bar" 可以扩展成:

"foo " + +"bar"
"foo " + NaN
"foo NaN"

2
不,它被解析为 ("foo" + (+"bar")) - Pointy
抱歉,使用Lisp风格的语法;我会澄清。 - David Wolever

1
这里的 + 是一个一元加运算符,它尝试将操作数转换为数字并按以下方式工作。
+"" //return 0
+"Some" //returns NaN

所以在这里。
"Hello " + + "World!" 

将会是

"Hello " + (+ "World!")
"Hello " + NaN
"Hello Nan"

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