为什么JavaScript处理string和数字之间的加号和减号运算符有区别?
我不明白为什么JavaScript这样工作。
console.log("1" + 1); console.log("1" - 1);
第一行打印11,第二个打印0.为什么JavaScript处理第一个作为一个string,第二个作为一个数字?
string连接是用+
完成的,所以Javascript会将第一个数字1转换为一个string,并将“1”和“1”连接成“11”。
你不能对string进行减法,所以Javascript将第二个“1”转换为一个数字,从1减1,结果为零。
+
是不明确的。 这可能意味着“连接” 或 “添加”。 因为一边是串,所以就是“串联”,结果是11(顺便说一句,这是我小时候最喜欢的笑话之一,那就是“1 + 1 =窗口”,就像可视化显示: │┼│ ニ ⊞
)
-
但是只有一个意思:减去。 所以它减去。
这种问题并不存在于其他语言,如PHP,其中“连接”是.
而不是+
,没有歧义。 还有一些像MySQL这样的语言甚至没有连接运算符,而是使用CONCAT(a,b,c...)
。
因为规范明确告诉这样做。 请注意11.6.1步骤5-8和11.6.2步骤5-7之间的差异。
11.6.1 – 描述添加操作符如何工作
1-4
。 …
5
。 让lprim成为原文(lval)。
6
。 让rprim成为原始(rval)。
7
。 如果Type(lprim)是String或Type(rprim)是String,那么
7a
。 返回连接ToString(lprim)和ToString(rprim)的string,
8
。 将加法操作的结果返回给ToNumber(lprim)和ToNumber(rprim)
11.6.2 – 介绍减法操作符如何工作
1-4
。 …
5
。 让lnum为ToNumber(lval)。
6
。 让rnum为ToNumber(rval)。
7
。 将减法运算的结果返回给lnum和rnum
总结如果任何一个操作数在没有任何提示的情况下被转换为原始值时突然变成了一个string,那么第二个被转换为一个string。 在减法的情况下,两个操作数都被转换成一个数字。
+
既是数字variables的加法运算符 ,又是string的连接运算符 。
只要在+
之后有一个string,Javascript就会select使用+
作为连接运算符,并在string周围尽可能多地转换(键入)尽可能多的术语,这样就可以连接它们。 这只是Javascript的行为。 (如果你尝试了console.log(23 + 2 + "." + 1 + 5 + "02" + 02);
,你会得到结果25.15022
,在连接之前把02
号键入到string2
中。
-
只能是一个减法运算符 ,所以当给定一个string时,会隐式地将string"1"
的types改为数字1
; 如果不这样做, "1" - 1
就没有办法了。 如果你试过console.log(23 + 2 + 1 + 5 - "02" + 03);
你会得到32 – string02
被转换成数字2
。 这个术语之后的术语必须能够被转换成一个数字。 如果你试过console.log(23 - 2 - "." - 1 - 5 - 02 - "02");
你会得到NaN
返回。
更重要的是,如果你试过console.log(23 + 2 + "." + 1 + 5 - "02" + 03);
,它将输出26.15
,之前的所有内容都被视为一个string(因为它包含一个string"."
,然后将-
之后的项视为一个数字。
JavaScript **中没有专门的string连接运算符。 加法运算符+
根据操作数的types执行string连接或添加:
"1" + 1 // "11" 1 + "1" // "11" 1 + 1 // 2
没有相反的连接(我认为)和减法运算符-
只执行减法,无论操作数的types如何:
"1" - 1 // 0 1 - "1" // 0 1 - 1 // 0 "a" - 1 // NaN
** .
PHP中的运算符和VB中的&
运算符是专用的string连接运算符。
根据标准的EcmaScript 262.当涉及到string时, +
和-
运算符的行为会有所不同。 第一个将每个值转换为一个string。 第二个将每个值转换为一个数字。
从标准:
如果Type(lprim)是String或Type(rprim)是String,则返回连接ToString(lprim)和ToString(rprim)的string,
这个规则意味着如果在expression式中有一个string值,那么在+
操作中涉及的所有值都将被转换为一个string。 在JavaScript中,当+
运算符与string一起使用时,它将它们连接起来。 这就是为什么console.log("5"+1)
返回“51”。 1
转换为string,然后将“5”+“1”连接在一起。
不过,上述规则不适用于-
运营商。 当你使用一个-
所有的价值被转换为数字根据标准(见下文)。 因此,在这种情况下, "5"
被转换为5
,然后减去1
。
从标准:
5让lnum为ToNumber(lval)。
6让rnum为ToNumber(rval)。
来自标准EcmaScript 262的操作员定义。
运营商+ : 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