我不明白为什么JavaScript会这样工作。
console.log("1" + 1);
console.log("1" - 1);
第一行显示11,第二行显示0。为什么JavaScript将第一行作为字符串处理而第二行作为数字处理?
我不明白为什么JavaScript会这样工作。
console.log("1" + 1);
console.log("1" - 1);
第一行显示11,第二行显示0。为什么JavaScript将第一行作为字符串处理而第二行作为数字处理?
Answers:
字符串连接完成 +
Java因此Javascript将第一个数字1转换为字符串,然后将“ 1”和“ 1”连接为“ 11”。
您无法对字符串执行减法运算,因此Javascript将第二个“ 1”转换为数字,并从1中减去1,从而得出零。
[] + {}
,基本上就可以做到[].toString() + ({}).toString()
(因为JavaScript在连接它们之前将涉及的数组和对象转换为字符串)。并且,因为[].toString === ''
和({}).toString() === '[object Object]'
,您的最终结果为[] + {} === '[object Object]'
。这是完全合乎逻辑的。
{} + []
呢 :)继续使用相同的逻辑:)
+
符号在其前面(例如如何+new Date
返回数值)所述的Date
对象(UNIX时间戳),或者+true
返回的数值true
,这是1
)。因此,加法变为{} + 0
。由于对象没有数值,因此变成+0
,JavaScript输出为0
。
[] + {}
执行串联而{} + []
不能呢?另外,您关于“对象没有数值”的说法是错误的:+{}
return NaN
。而且NaN + 0
是NaN
,不0
。就像@Yury所说的那样,从实际情况或常识的角度讨论JavaScript类型强制是毫无意义的。
[] + {}
和{} + []
实际上是两个完全不同的语句
+
是模棱两可的。它可以表示“连接”或“添加”。由于一侧是一个字符串,因此它的意思是“连接”,因此结果为11(顺便说一句,这是我小时候最喜欢的笑话之一。“ 1 + 1 =窗口”直观显示:│┼│ ニ ⊞
)
-
但是只有一个意思:减。因此它减去。
在其他语言(例如PHP)中,“ concatenate”.
代替,不会出现这种问题+
,因此不会产生歧义。像MySQL这样的其他语言甚至都没有连接运算符,而是使用CONCAT(a,b,c...)
。
因为规范明确指示要这样做。Page75。请注意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应用减法运算的结果
总结 在加法的情况下,如果任何操作数在转换为没有任何提示的原始值时突然变成字符串,则第二个操作数也将转换为字符串。在减法的情况下,两个操作数都将转换为数字。
[] + [] === ""
:)是由于串联与加法之间的模棱两可吗?大声笑
+
既是数字变量的加法运算符,也是串联运算符,也是字符串。
每当在后面有一个字符串时+
,JavaScript都会选择使用+
as作为串联运算符,并在该字符串周围尽可能多地转换(键入)术语,以便可以将它们串联起来。那只是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
,之前的所有内容都-
被视为字符串(因为它包含string "."
,然后在之后的术语-
被视为数字)。
根据标准EcmaScript262。+
和-
涉及字符串时运算符的行为不同。第一个将每个值转换为字符串。第二个将每个值转换为数字。
从标准:
如果Type(lprim)为String或Type(rprim)为String,则返回将ToString(lprim)与ToString(rprim)串联后得到的字符串
该规则意味着,如果表达式中有一个字符串值,则该+
操作中涉及的所有值都将转换为字符串。在JavaScript中,当+
运算符与字符串一起使用时,它将它们连接起来。这就是为什么console.log("5"+1)
返回“ 51”的原因。1
转换为字符串,然后将“ 5” +“ 1”连接在一起。
但是,以上规则不适用于-
运算符。使用a时,-
所有值都将根据标准转换为数字(请参见下文)。因此,在这种情况下,"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