(Firefox32,Win 7)
使用暂存器时:
var a = "2";
console.log('a',a);
a = 1-1 + a;
console.log('a',a);
a = 1 + a -1;
console.log('a',a);
在控制台中引导:
"a" "2"
"a" "02"
"a" 101
我做错了吗?
我确信我已经经常将字符串转换为数字,并且它有效。 (虽然我更喜欢使用显式转换函数,但因为它如此完美地工作了很长时间,......:/)
为什么第三行是一个数字?但不是第二个?为什么是101?
答案 0 :(得分:4)
在完成stringvar = 1 + stringvar?
之后,是不是应该将字符串转换为数字?
不。 :-)如果 操作数是一个字符串,它是字符串连接,而不是添加。这由§11.6.1 of the spec在第7步中定义:
- 让lref成为评估AdditiveExpression的结果。
- 让lval成为GetValue(lref)。
- 让rref成为评估MultiplicativeExpression的结果。
- 让rval为GetValue(rref)。
- 让lprim为ToPrimitive(lval)。
- 让rprim为ToPrimitive(rval)。
- 如果Type(lprim)是String 或 Type(rprim)是String,那么
- 返回串联ToString(lprim)后跟ToString(rprim)的结果的字符串
- 将添加操作的结果返回到ToNumber(lprim)和ToNumber(rprim)。参见下面的注释11.6.3。
醇>
(我强调“或”)
重申您的第三个示例,1 + a - 1
其中a
为"02"
:
1 + "02" - 1
加法(二进制+
)和减法(二进制-
)运算符具有相同的优先级,并且都是从左到右关联的,因此执行如下:
(1 + "02") - 1 => "102" - 1 => 101
+
是字符串连接,但由于subtraction operator -
始终适用于数字,因此在扣除{"102"
之前强制102
1
{1}}从中获取101
。
答案 1 :(得分:3)
这是字符串连接的工作原理。
// Number + String -> concatenation 5 + "foo" // "5foo"
您可以使用Unary Plus operator (+
)来解决此问题,以避免拨打parseInt
:
a = 1 + +a;
一元加(
+
)一元加运算符在其操作数之前,并计算其操作数,但是如果它已经没有,则尝试将其转换为数字。虽然一元否定( - )也可以转换非数字,但是一元加号是将某些东西转换为数字的最快和最优选的方式,因为它不会对数字执行任何其他操作。