( 'b' + 'a' + + 'a' + 'a')。toLowerCase() 'banana'の結果はなぜですか?


575

友人の1人がこのJavaScriptコードに出会ったとき、私はいくつかのJavaScriptを練習していました。

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

上記のコードは答えます"banana"!なぜ誰かが説明できますか?


22
その2番目のプラスは単項演算子です:+"a"is NaN
ヘラルド

8
コンソールで、+'a'自分で書いて何が起こるか見てみましょう。
一部のプログラマー、

23
そして、もっと熱心な人のために。すべてのファンリストを
Giddy Naya

4

回答:


566

+'a'NaN( "Not a Number")に解決されます。これは、文字列を数値に強制変換する一方で、文字aを数値として解析できないためです。

document.write(+'a');
小文字になりbananaます。

型変換による文字列への追加NaNを追加する"ba"と、が得られます。そして、後ろにあります。NaN"NaN"baNaNabaNaNa

間のスペース+ +は、最初の1つの文字列連結と2番目の文字列を単項プラス(つまり、「正」)演算子にするためのものです。を使用しても同じ結果が得'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'を使用して数値に変換しようとします。は数値ではないため、結果は ("Not-A-Number")になります。'a'NaN

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

NaN「非数」の略で、それはまだ数値だタイプ。文字列に追加すると、他の数値と同じように連結されます。

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

最後に、小文字です:

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

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

明確にするために、これを2つのステップに分けてみましょう。まず、括弧で囲まれた式の値を取得toLowerCase()し、その結果に関数を適用します。

第一歩

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

LRに行くと、次のようになります。

  • 'b' + 'a'baを返します。これは通常の連結です。
  • ba + + 'a'baとを連結しようとし+ 'a'ます。ただし、単項演算子+はオペランドを数値に変換しようとするため、値NaNが返され、元のbaと連結すると文字列に変換され、結果としてbaNaNになります。
  • baNaN+ 'a'はbaNaNaを返します。繰り返しますが、これは通常の連結です。

この段階では、ステップ1の結果はbaNaNaです。

ステップ2

.toLowerCase()ステップ1から返された値に適用すると、次のようになります。

バナナ

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

次の2つの方法で文字列を数値に変換できます。

  1. 数値(文字列);
  2. +文字列;

元のクエリに戻ります。ここでは次の文字( '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);


9

このコード行は、式を評価してから、戻り値に基づいてメソッドを呼び出します。

('b' + 'a' + + 'a' + 'a')は、文字列リテラルと加算演算子のみで構成されています。

  • 文字列リテラル「文字列リテラルは、一重引用符または二重引用符で囲まれた0個以上の文字です。」
  • 加算演算子(+)「加算演算子は、文字列連結または数値加算を実行します。」

実行される暗黙のアクションは、文字列に対するToNumberの呼び出しです。

  • 文字列型に適用されるToNumber「文字列に適用されるToNumberは、入力文字列に文法を適用します。文法が文字列をStringNumericLiteralの拡張として解釈できない場合、ToNumberの結果はNaNになります。」

インタープリターには、式を左手式と右手式のコンポーネントに分解することにより、式を解析する方法のルールがあります。


ステップ1: 'b' + 'a'

左の式:'b'
左の値: 'b'

演算子:+(式の片側が文字列なので、文字列を連結します)

正しい表現:'a' 正しい値: 'a'

結果: 'ba'


ステップ2: 'ba' + + 'a'

左の式:'ba'
左の値: 'ba'

演算子:+(式の片側が文字列なので、文字列を連結します)

右の式:(+ 'a'これは+記号からの正の数であると仮定して、文字 'a'の数学値を評価します-負の記号もここで機能し、負の数を示します-これはNaNになります)
右の値: NaN(演算子は文字列連結であるため、連結中にこの値に対してtoStringが呼び出されます)

結果: 'baNaN'


ステップ3: 'baNaN' + 'a'

左の式:'baNaN'
左の値: 'baNaN'

演算子:+(式の片側が文字列なので、文字列を連結します)

正しい表現:'a'
正しい値: 'a'

結果: 'baNaNa'


この後、グループ化式が評価され、toLowerCaseが呼び出されてバナナが残ります。


7

+を使用すると、JavaScriptで任意の値がNumberに変換されます。

そう...

ここで最初に知って学ぶべき主なことは+、JavaScriptの値の前に使用することです。その値は数値に変換されますが、その値を変換できない場合、JavaScriptエンジンはNaNを返します。つまり、数値ではありません(できない以下のように、数値、メイトに変換されます!)およびストーリーの残りの部分:

( 'b' + 'a' + + 'a' + 'a')。toLowerCase() 'banana'の結果はなぜですか?



0

ここで魔法を見てください。2番目のプラスは「NaN」を与える単項演算子です

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.