私の友人の一人がこのJavaScriptコードに出くわしたとき、私はJavaScriptを練習していました。
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());
上記のコードは"banana"
!誰でもその理由を説明できますか?
'b' + 'a' + + 'a' + 'a'
...として評価されます...
('b') + ('a') + (+'a') + ('a')
(参照: 演算子の優先順位 )
(+'a')
変換を試みます'a'
を使用して数値に 単項プラス演算子 を使用します。なぜなら'a'
は数値ではなく、結果は NaN
( "Not-A-Number") :
'b' + 'a' + NaN + 'a'
NaN
は「Not a Number」の略ですが、数値typeです。文字列に追加されると、他の数値と同様に連結されます。
'b' + 'a' + NaN + 'a' => 'baNaNa'
最後に、小文字です:
'baNaNa'.toLowerCase() => 'banana'
_('b' + 'a' + + 'a' + 'a').toLowerCase()
_
明確にするために、これを2つのステップに分けましょう。最初に、括弧で囲まれた式の値を取得してから、結果にtoLowerCase()
関数を適用します。
_'b' + 'a' + + 'a' + 'a'
_
L-Rに進むと、次のようになります。
'b' + 'a'
_はbaを返します。これは通常の連結です。ba + + 'a'
_は、baと_+ 'a'
_の連結を試みます。ただし、単項演算子_+
_はオペランドを数値に変換しようとするため、値NaNが返され、元の文字と連結されたときに文字列に変換されますba-したがって、baNaNになります。baNaN
+ 'a'はbaNaNaを返します。繰り返しますが、これは通常の連結です。この段階では、ステップ1の結果はbaNaNaです。
ステップ1から返された値に.toLowerCase()
を適用すると、次のようになります。
バナナ
JavaScriptには、チェックアウトできる多くの 類似のしゃれ があります。
+演算子のためだけです。
チャンクからさらに知識を得ることができます。
=> ( ('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つの方法で文字列を数値に変換できます。
元のクエリに戻ります。ここでは、次の文字( '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);
このコード行は式を評価し、戻り値に基づいてメソッドを呼び出します。
表現 ('b' + 'a' + + 'a' + 'a')
は、文字列リテラルと加算演算子のみで構成されています。
実行される暗黙的なアクションは、文字列に対するToNumberの呼び出しです
- 文字列型に適用されるToNumber 「文字列に適用されるToNumberは、入力文字列に文法を適用します。文法がStringNumericLiteralの展開として文字列を解釈できない場合、ToNumberの結果はNaNです。」
インタプリタには、式を左手式と右手式のコンポーネントに分解することにより、式を解析する方法のルールがあります。
ステップ1: 'b' + 'a'
左式:'b'
左の値: 'b'
演算子:+(式の側面の1つは文字列なので、文字列の連結)
正しい表現:'a'
正しい値: 'a'
結果:'ba'
ステップ2: 'ba' + + 'a'
左式:'ba'
左の値: 'ba'
演算子:+(式の側面の1つは文字列なので、文字列の連結)
正しい表現:+ 'a'
(これは、文字 'a'の数学値を評価します。これは、+記号からの正の数であると仮定します-負の数を示すマイナス記号もここで機能します-NaNになります)
右の値:NaN(演算子は文字列連結であるため、連結中にこの値でtoStringが呼び出されます)
結果: 'baNaN'
ステップ3:'baNaN' + 'a'
左式:'baNaN'
左の値: 'baNaN'
演算子:+(式の側面の1つは文字列なので、文字列の連結)
正しい表現:'a'
右の値: 'a'
結果: 'baNaNa'
この後、グループ化式が評価され、toLowerCaseが呼び出され、バナナが残ります。
NaNの詳細は W3Schools または Mozilla Developer Network でご覧ください
こちらの魔法をご覧ください。 2番目のプラスは、 'NaN'を与える単項演算子です
console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());