为什么('b'+'a'+ +'a'+'a')。toLowerCase()'banana'的结果?


575

当我的一个朋友遇到以下JavaScript代码时,我正在练习一些JavaScript:

document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());

上面的代码答案"banana"!谁能解释为什么?


22
第二个加号是一元运算符:+"a"is NaN
Gerardo Furtado

8
在控制台中,+'a'自己编写并查看会发生什么。
程序员伙计,

23
对于那些渴望更多的人。查看完整的娱乐清单
Giddy Naya


Answers:


566

+'a'解析为NaN(“非数字”),因为它会将字符串强制转换为数字,而字符a不能解析为数字。

document.write(+'a');
小写变成banana

添加NaN"ba"轮流NaN到字符串"NaN"由于类型转换,给人baNaN。然后有一个a背后,给予baNaNa

两者之间的空间+ +是使第一个字符串串联而第二个字符串为一元加号(即“正”)运算符。如果使用'ba'+(+'a')+'a',则解析为'ba'+NaN+'a',则得到的结果相同,这'ba'+'NaN'+'a'与类型变戏法等价。

document.write('ba'+(+'a')+'a');


90
'b' + 'a' + + 'a' + 'a'

被评估为...

('b') + ('a') + (+'a') + ('a')

(请参阅:运算符优先级

(+'a')尝试'a'使用一元加运算符将其转换为数字。因为'a'不是数字,所以结果为NaN“ Not-A-Number”):

'b'  +  'a'  +  NaN  + 'a'

尽管NaN代表“不是数字”,但它仍然是数字类型;当添加到字符串中时,它的连接方式与任何其他数字相同:

'b'  +  'a'  +  NaN  + 'a'  =>  'baNaNa'

最后,它是小写的:

'baNaNa'.toLowerCase()      =>  'banana'

36
('b' + 'a' + + 'a' + 'a').toLowerCase()

为了清楚起见,我们将其分为两个步骤。首先,我们获得括号表达式的值,然后应用toLowerCase()函数应用于结果。

步骤1

'b' + 'a' + + 'a' + 'a'

走向LR,我们有:

  • 'b' + 'a'返回ba,这是常规连接。
  • ba + + 'a'尝试将ba与连接+ 'a'。但是,由于一元运算符+尝试将其操作数转换为数字,所以将返回值NaN,然后将其与原始ba串联时将其转换为字符串-从而导致baNaN
  • baNaN+'a'返回baNaNa。同样,这是常规连接。

在这一阶段,第一步的结果是baNaNa

第二步

应用.toLowerCase()从第一步返回的值可以得出:

香蕉

您可以签出JavaScript 中许多类似的双关语


24

只是因为 +运算符。

我们可以从块中获取更多的知识。

=> ( ('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';

您可以通过两种方式将字符串转换为数字:

  1. 数字(字符串);
  2. +字串;

回到原始查询;在这里,它尝试将下一个字符('a')转换为数字,但突然我们收到错误NaN,

( ('b') + ('a') + (+'a') + ('a'))
( ('b') + ('a') + NaN + ('a'))

但是它被视为字符串,因为前一个字符在字符串中。所以会的

( ('b') + ('a') + 'NaN' + ('a'))

最后将其转换为LowerCase(),因此它是香蕉

如果您旁边输入数字,您的结果将改变。

( '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);


9

这行代码评估一个表达式,然后根据返回的值调用一个方法。

该表达式('b' + 'a' + + 'a' + 'a')仅由字符串文字和加法运算符组成。

  • 字符串文字 “字符串文字是用单引号或双引号引起来的零个或多个字符。”
  • 加法运算符(+) “加法运算符执行字符串连接或数字加法。”

采取的隐式操作是在字符串上调用ToNumber

  • 应用于字符串类型的 ToNumber“应用于字符串的ToNumber将语法应用于输入的String。如果语法无法将String解释为StringNumericLiteral的扩展,则ToNumber的结果为NaN。”

解释器具有将表达式分解为左右两个表达式的组成部分的规则。


步骤1: 'b' + 'a'

左表情: 'b'
左值:'b'

运算符:+(表达式的一面是字符串,因此是字符串连接)

正确的表达方式: 'a' 正确的值:“ a”

结果: 'ba'


第2步: 'ba' + + 'a'

左表情: 'ba'
左值:'ba'

运算符:+(表达式的一面是字符串,因此是字符串连接)

正确的表达式:(+ 'a'假设字符'a'的数学值假定是+号的正数-负号在这里也可以表示负数,这会导致NaN)。
正确的表达式: NaN(因为运算符是字符串连接,所以在连接期间在此值上调用toString)

结果:“ baNaN”


第三步: 'baNaN' + 'a'

左表达式:'baNaN'
左值:'baNaN'

运算符:+(表达式的一面是字符串,因此是字符串连接)

正确的表达方式:'a'
正确的值:“ a”

结果:“ baNaNa”


在此之后,对分组表达式进行了评估,并调用了toLowerCase,这给我们留下了香蕉。


7

使用+将在JavaScript中将任何值转换为Number!

所以...

首先要了解和学习的主要内容是+在JavaScript中的任何值之前使用该值,将其转换为数字,但是如果该值无法转换,则JavaScript引擎将返回NaN,这意味着不是数字(不能转换为数字,交配!),故事的其余内容如下:

为什么('b'+'a'+ +'a'+'a')。toLowerCase()'banana'的结果?



0

在这里看到魔术。第二个加号是提供'NaN'的一元运算符

console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.