我不明白为什么JavaScript会这样运作。
console.log("1" + 1);
console.log("1" - 1);
第一行打印11,第二行打印0。 为什么JavaScript将第一个作为String处理,第二个作为数字处理?
答案 0 :(得分:92)
字符串连接是使用+
完成的,因此Javascript会将第一个数字1转换为字符串,并将“1”和“1”连接成“11”。
您无法对字符串执行减法,因此Javascript会将第二个“1”转换为数字,并从1减去1,结果为零。
答案 1 :(得分:33)
+
含糊不清。它可以表示“连接”或“添加”。由于一边是一个字符串,它被认为是“连接”,因此结果是11(顺便说一下,这是我小时候最喜欢的笑话之一。那和“1 + 1 =窗口”,如同视觉显示:│┼│ ニ ⊞
)
-
但只有一个含义:减去。所以它减去了。
这种问题在PHP等其他语言中不存在,其中“连接”是.
而不是+
,没有任何歧义。还有其他语言如MySQL甚至没有连接运算符,而是使用CONCAT(a,b,c...)
。
答案 2 :(得分:22)
因为the spec明确告知这样做。 第75页。注意11.6.1步骤5-8和11.6.2步骤5-7之间的区别。
11.6.1 - 描述加法运算符的工作原理
1-4
。 ...
5
。设lprim为ToPrimitive(lval)。
6
。设rprim为ToPrimitive(rval)。
7
。如果Type(lprim)是String或Type(rprim)是String,那么
7a
。返回串联ToString(lprim)后跟ToString(rprim)的结果的字符串
8
。将添加操作的结果返回到ToNumber(lprim)和ToNumber(rprim)
11.6.2 - 描述减法运算符的工作原理
1-4
。 ...
5
。让lnum为ToNumber(lval)。
6
。设rnum为ToNumber(rval)。
7
。将减法运算的结果返回到lnum和rnum
<强>摘要强> 在添加的情况下,如果在没有任何提示的情况下转换为原始值时任何操作数突然变为字符串,则第二个操作数也将转换为字符串。在减法的情况下,两个操作数都被转换为数字。
答案 3 :(得分:7)
+
既是数字变量的加法运算符,也是字符串的连接运算符。
每当在+
之后出现一个字符串时,Javascript将选择使用+
作为连接运算符,并在字符串周围转换(键入)尽可能多的术语,以便它可以连接他们。这只是Javascript的行为。 (如果您尝试console.log(23 + 2 + "." + 1 + 5 + "02" + 02);
,则会得到结果25.15022
。在连接之前,数字02
已输入字符串2
。
-
只能是减法运算符,所以当给定字符串时,它会隐式地将字符串"1"
的类型更改为数字1
;如果它没有这样做,那么"1" - 1
就没有办法了。如果您尝试console.log(23 + 2 + 1 + 5 - "02" + 03);
,那么您将获得32 - 字符串02
将转换为数字2
。 -
之后的术语必须能够转换为数字;如果您尝试console.log(23 - 2 - "." - 1 - 5 - 02 - "02");
,则会返回NaN
。
更重要的是,如果您尝试console.log(23 + 2 + "." + 1 + 5 - "02" + 03);
,则会输出26.15
,其中-
之前的所有内容都被视为字符串(因为它包含字符串"."
,并且然后将-
之后的术语视为数字。
答案 4 :(得分:6)
JavaScript **中没有专用的字符串连接运算符。加法运算符+
执行字符串连接或添加,具体取决于操作数的类型:
"1" + 1 // "11"
1 + "1" // "11"
1 + 1 // 2
没有连接的反面(我认为)和减法运算符-
只执行减法而不管操作数的类型:
"1" - 1 // 0
1 - "1" // 0
1 - 1 // 0
"a" - 1 // NaN
** PHP中的.
运算符和VB中的&
运算符是专用字符串连接运算符。
答案 5 :(得分:3)
根据标准EcmaScript 262. +
和-
运算符在涉及字符串时表现不同。第一个将每个值转换为字符串。第二个将每个值转换为数字。
来自标准:
如果Type(lprim)是String或Type(rprim)是String,则返回 字符串,它是连接ToString(lprim)后跟的结果 的ToString(rprim)
此规则意味着如果在表达式中存在字符串值,则+
操作中涉及的所有值都将转换为字符串。在JavaScript中,当+
运算符与字符串一起使用时,它会将它们连接起来。这就是console.log("5"+1)
返回&#34; 51&#34;的原因。 1
转换为字符串然后,&#34; 5&#34; +&#34; 1&#34;连在一起。
尽管如此,上述规则并不适用于-
运营商。当您使用-
时,所有值都会根据标准转换为数字(参见下文)。因此,在这种情况下,"5"
会转换为5
,然后会减去1
。
来自标准:
5让lnum为ToNumber(lval)。
6让rnum为ToNumber(rval)。
运营商+ :http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1
操作员:http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2
答案 6 :(得分:0)
使用加号和字符串""
基本上会返回一个字符串,因为您正在执行串联:
typeof ("" + 1 + 0) // string
typeof (1 + 0) // number
当使用-
时,您可以转换为数字,因为可以进行字符串连接:
typeof ("" - 1 + 0) // number