【问题标题】:Why is the result of ('b'+'a'+ + 'a' + 'a').toLowerCase() 'banana'?为什么 ('b'+'a'+ + 'a' + 'a').toLowerCase() 'banana' 的结果是?
【发布时间】:2026-02-15 01:45:02
【问题描述】:
当我的一个朋友偶然发现这段 JavaScript 代码时,我正在练习一些 JavaScript:
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());
以上代码回答"banana"!
谁能解释一下为什么?
【问题讨论】:
标签:
javascript
type-conversion
【解决方案1】:
+'a' 解析为 NaN(“非数字”),因为它将字符串强制转换为数字,而字符 a 不能被解析为数字。
小写它变成
banana。
由于类型转换,将NaN 添加到"ba" 将NaN 变成字符串"NaN",得到baNaN。
然后后面有个a,给baNaNa。
+ + 之间的空格是为了使第一个字符串连接和第二个一元加号(即“正”)运算符。
如果使用'ba'+(+'a')+'a',则结果相同,解析为'ba'+NaN+'a',由于类型杂乱,相当于'ba'+'NaN'+'a'。
document.write('ba'+(+'a')+'a');
【解决方案2】:
'b' + 'a' + + 'a' + 'a'
...被评估为...。
'b' + 'a' + (+'a') + 'a'
(见:operator precedence)
(+'a') 尝试使用unary plus operator 将'a' 转换为数字。因为'a' 不是数字,所以结果是NaN ("Not a Number"):
'b' + 'a' + NaN + 'a'
虽然NaN 代表“Not a Number”,但它仍然是一个数字类型;添加到字符串时,它会像任何其他数字一样连接:
'b' + 'a' + NaN + 'a' => 'baNaNa'
最后是小写的:
'baNaNa'.toLowerCase() => 'banana'
【解决方案3】:
('b' + 'a' + + 'a' + 'a').toLowerCase()
为清楚起见,让我们将其分为两个步骤。首先,我们获取括号表达式的值,然后对结果应用toLowerCase() 函数。
第一步
'b' + 'a' + + 'a' + 'a'
从左到右,我们有:
-
'b' + 'a' 返回 ba,这是常规连接。
-
ba + + 'a' 尝试将 ba 与 + 'a' 连接起来。但是,由于一元运算符 + 试图将其操作数转换为数字,因此返回值 NaN,然后将其与原始 ba连接时转换为字符串> - 从而导致 baNaN。
-
baNaN + 'a' 返回 baNaNa。同样,这是常规连接。
在这个阶段,第一步的结果是baNaNa。
第二步
对从第一步返回的值应用.toLowerCase() 给出:
香蕉
您可以在 JavaScript 中查看许多 similar puns。
【解决方案4】:
这只是因为 + 运算符。
我们可以从chunk中得到更多的知识。
=> ( ('b') + ('a') + (++) + ('a') + ('a'))
=> ( ('b') + ('a') + (+) + ('a') + ('a')) // Here + + convert it to +operator
Which later on try to convert next character to the number.
例如
const string = '10';
您可以通过两种方式将字符串转换为数字:
- 数字(字符串);
- +字符串;
回到原来的查询;
在这里它尝试将下一个字符('a')转换为数字,但突然出现错误 NaN,
( ('b') + ('a') + (+'a') + ('a'))
( ('b') + ('a') + NaN + ('a'))
但它被视为字符串,因为前一个字符在字符串中。
所以会是
( ('b') + ('a') + 'NaN' + ('a'))
最后将它转换为toLowerCase(),所以它会是香蕉
如果你把数字放在它旁边,你的结果会改变。
( 'b' + 'a' + + '1' + 'a' )
应该是'ba1a'
const example1 = ('b' + 'a' + + 'a' + 'a').toLowerCase(); // 'banana'
const example2 = ('b' + 'a' + + '1' + 'a').toLowerCase(); // 'ba1a'
console.log(example1);
console.log(example2);
【解决方案5】:
这行代码计算一个表达式,然后根据返回值调用一个方法。
表达式('b' + 'a' + + 'a' + 'a') 完全由字符串文字和加法运算符组成。
所采取的隐式操作是对字符串的 ToNumber 调用
解释器有如何解析表达式的规则,通过将其分解为左手和右手表达式的组成部分。
第一步:'b' + 'a'
左表达式:'b'
左值:'b'
运算符:+(表达式的一侧是字符串,所以字符串连接)
正确表达:'a'
正确的值:'a'
结果:'ba'
第二步:'ba' + + 'a'
左表达式:'ba'
左值:'ba'
运算符:+(表达式的一侧是字符串,所以字符串连接)
正确的表达式:+ 'a'(这会评估字符“a”的数学值,假设它是 + 号的正数 - 负号在这里也可以表示负数 - 结果以 NaN 为单位)
右值:NaN(因为操作符是字符串拼接,拼接时对这个值调用toString)
结果:'baNaN'
第三步:'baNaN' + 'a'
左表达式:'baNaN'
左值:'baNaN'
运算符:+(表达式的一侧是字符串,所以字符串连接)
正确表达:'a'
正确的值:'a'
结果:'baNaNa'
在这之后,分组表达式被评估,toLowerCase 被调用,这给我们留下了香蕉。
【解决方案6】:
在 JavaScript 中使用 + 将任何值转换为数字!
所以...
这里首先要了解和学习的主要内容是在 JavaScript 中的任何值之前使用+,会将该值转换为数字,但如果该值无法转换,则 JavaScript 引擎将返回 NaN,这意味着,不是数字(不能转换为数字,伙计!),其余的故事如下:
【解决方案8】:
在这里看到魔法。第二个加号是一个一元运算符,它给出'NaN'
console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());