【问题标题】:Why is the result of ('b'+'a'+ + 'a' + 'a').toLowerCase() 'banana'?为什么 (\'b\'+\'a\'+ + \'a\' + \'a\').toLowerCase() 的结果是 \'banana\'?
【发布时间】:2022-12-07 13:25:41
【问题描述】:
当我的一位朋友遇到这段 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(“不是数字”):
'b' + 'a' + NaN + 'a'
虽然NaN代表“不是数字”,但它仍然是一个数字类型;当添加到字符串时,它会像任何其他数字一样连接:
'b' + 'a' + NaN + 'a' => 'baNaNa'
最后,它是小写的:
'baNaNa'.toLowerCase() => 'banana'
【解决方案3】:
('b' + 'a' + + 'a' + 'a').toLowerCase()
为了清楚起见,让我们将其分为两个步骤。首先,我们获取括号表达式的值,然后对结果应用 toLowerCase() 函数。
第一步
'b' + 'a' + + 'a' + 'a'
去左-右, 我们有:
-
'b' + 'a'回报吧,这是常规连接。
-
ba + + 'a' 尝试连接吧与+ 'a'。但是,由于一元运算符 + 试图将其操作数转换为数字,因此值钠返回,然后在与原始字符串连接时转换为字符串吧- 从而导致钡钠.
-
baNaN + 'a' 返回香蕉.同样,这是常规连接。
在这个阶段,第一步的结果是香蕉.
第二步
对从第一步返回的值应用 .toLowerCase() 给出:
香蕉
JavaScript 中有很多similar puns,您可以查看。
【解决方案4】:
只是因为+操作员。
我们可以从 chunk it 中获得更多的知识。
=> ( ('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 引擎将返回钠, 意思是,不是数字(不能转换成数字,伙计!)剩下的故事如下:
【解决方案8】:
看看这里的魔法。第二个加号是一元运算符,它给出 'NaN'
console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());