为什么的结果(& # 39;b # 39; + & # 39;一个# 39;+ + & # 39;一个# 39;+ 'a').toLowerCase() '香蕉'?

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

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

The above code answers "banana"! Can anyone explain why?

115747 次浏览

+'a'解析为NaN(“不是一个数字”),因为它将一个字符串强制为一个数字,而字符a不能解析为一个数字。

document.write(+'a');
To lowercase it becomes banana.

Adding NaN to "ba" turns NaN into the string "NaN" due to type conversion, gives baNaN. And then there is an a behind, giving baNaNa.

The space between + + is to make the first one string concatenation and the second one a unary plus (i.e. "positive") operator. You have the same result if you use 'ba'+(+'a')+'a', resolved as 'ba'+NaN+'a', which is equivalent to 'ba'+'NaN'+'a' due to type juggling.

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

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

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

第一步

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

点击唐森,我们有:

  • 'b' + 'a'返回英航,这是常规的连接。
  • ba + + 'a'尝试连接英航+ 'a'。然而,由于一元操作符+试图将其操作数转换为数字,因此返回值,然后在与原始的英航连接时将其转换为字符串——从而产生巴南区
  • baNaN + 'a'返回香蕉。同样,这是常规的串联。

在此阶段,第一步的结果是香蕉

第二步

对第一步返回的值应用.toLowerCase()会得到:

香蕉

JavaScript中有许多类似的双关语代码,您可以查看。

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

...评估为....

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

# EYZ0 > < /晚餐

(+'a')尝试将'a'转换为使用一元加算符的数字。因为'a'不是一个数字,所以结果是NaN (“不是一个数字”;):

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

虽然NaN代表“不是数字”,但它仍然是一个数字类型;当添加到字符串时,它就像任何其他数字一样连接:

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

最后,它是小写的:

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

这只是因为+操作符。

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

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

最后它将其转换为toLowerCase(),因此它将是banana

如果你把数字放在它旁边,你的结果将会改变。

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

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

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

  • 字符串字面量是0个或多个用单引号或双引号括起来的字符。
  • “加法运算符执行字符串连接或数字加法。”

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

  • 应用于字符串类型的ToNumber "ToNumber应用于字符串将语法应用于输入字符串。如果语法不能将String解释为StringNumericLiteral的扩展,那么ToNumber的结果就是NaN。”

解释器具有如何解析表达式的规则,方法是将表达式分解为左手表达式和右手表达式的组件。


步骤1:'b' + 'a'

左表达式:'b'
左值:'b'

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

正确表达:'a' 正确值:'a'

结果:# EYZ0


第二步:'ba' + + 'a'

左表达式:'ba'
左值:'ba'

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

正确表达式:+ 'a'(它计算字符“a”的数学值,假设它是一个来自正号的正数——负号也可以在这里工作,表示负数——结果是NaN)
右值:NaN(因为操作符是字符串连接,所以在连接期间对该值调用toString)

结果:“巴南区”


第三步:'baNaN' + 'a'

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

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

正确表达:'a'
正确值:'a'

结果:“香蕉”


在此之后,分组表达式已经被求值,并调用toLowerCase,这给我们留下了banana。

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

所以…

这里首先要了解和学习的主要事情是在JavaScript中的任何值+之前使用+,但如果该值不能转换,JavaScript引擎将返回,这意味着不是数字(不能转换为数字,朋友!)和下面的故事:

Why is result of ('b'+'a'+ +'+ & # 39;一个# 39;).toLowerCase() & # 39;香蕉# 39;? < / >

看看这里的魔力吧。第二个加号是一个一元运算符,它给出NaN

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

enter image description here

更多关于NaN的信息请访问W3SchoolsMozilla开发者网络