Dlaczego wynik („b” + „a” + + „a” + „a”). ToLowerCase () „banana”?


575

Ćwiczyłem trochę JavaScript, gdy jeden z moich przyjaciół natknął się na ten kod JavaScript:

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

Powyższy kod odpowiada "banana"! Czy ktoś może wyjaśnić, dlaczego?


22
Ten drugi plus to jednoargumentowy operator: +"a"jest NaN.
Gerardo Furtado,

8
W konsoli pisz +'a'samodzielnie i zobacz, co się stanie.
Jakiś programista koleś

23
I dla tych, którzy chcą więcej. Zobacz pełną listę zabaw
Giddy Naya,

4
Silnie powiązane: stackoverflow.com/q/9032856
Kyll

Odpowiedzi:


566

+'a'rozwiązuje na NaN(„Not a Number”), ponieważ wymusza ciąg znaków na liczbę, podczas gdy znak anie może zostać przeanalizowany jako liczba.

document.write(+'a');
Małe litery stają się banana.

Dodanie NaNdo "ba"zamienia NaNsię w łańcuch "NaN"ze względu na konwersję typu, daje baNaN. A potem jest atyłek, dawanie baNaNa.

Odstęp między nimi + +ma uczynić pierwszy jeden ciąg konkatenacji, a drugi jednoargumentowy operator dodatni (tj. „Dodatni”). Masz ten sam wynik, jeśli używasz 'ba'+(+'a')+'a', rozwiązany jako 'ba'+NaN+'a', co jest równoważne z 'ba'+'NaN'+'a'powodu żonglowania typami.

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


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

... jest oceniany jako ...

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

(patrz: pierwszeństwo operatora )

(+'a')próbuje przekonwertować 'a'na liczbę za pomocą jednoargumentowego operatora plus . Ponieważ 'a'nie jest liczbą, wynikiem jest NaN ( „Nie-liczba” ):

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

Mimo, że NaNoznacza „Not a Number”, wciąż jest to typ liczbowy ; po dodaniu do ciągów łączy się tak, jak każda inna liczba:

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

Wreszcie jest małe:

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

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

Dla jasności podzielmy to na dwa kroki. Najpierw otrzymujemy wartość wyrażenia w nawiasach, a następnie stosujemy toLowerCase()funkcję do wyniku.

Krok pierwszy

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

Idąc LR , mamy:

  • 'b' + 'a'zwraca ba , jest to regularna konkatenacja.
  • ba + + 'a'próbuje połączyć ba z + 'a'. Ponieważ jednak operator jednoargumentowy +próbuje przekonwertować swój operand na liczbę, zwracana jest wartość NaN , która jest następnie przekształcana w ciąg po połączeniu z oryginalnym ba - w ten sposób uzyskując baNaN .
  • baNaN+ „a” zwraca baNaNa . Znowu jest to regularna konkatenacja.

Na tym etapie wynikiem kroku pierwszego jest baNaNa .

Krok drugi

Zastosowanie .toLowerCase()wartości zwróconej z kroku pierwszego daje:

banan

W JavaScript jest wiele podobnych kalamburów , które możesz sprawdzić.


24

To tylko z powodu operatora + .

Dalszą wiedzę możemy uzyskać z fragmentu.

=> ( ('b') + ('a') + (++) + ('a') + ('a'))
=> ( ('b') + ('a') + (+) + ('a') + ('a')) // Here + + convert it to +operator 
Which later on try to convert next character to the number.

Na przykład

const string =  '10';

Możesz przekonwertować ciąg na liczbę na 2 sposoby:

  1. Liczba (ciąg);
  2. + ciąg;

Wróćmy do pierwotnego zapytania; Tutaj próbuje przekonwertować następny znak („a”) na liczbę, ale nagle otrzymaliśmy błąd NaN,

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

Ale traktuje to jako ciąg, ponieważ poprzedni znak był w ciągu. Tak będzie

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

I na koniec konwertuje to na LowerCase (), więc byłby bananem

Jeśli obok znajdziesz numer, Twój wynik ulegnie zmianie.

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

Byłby to „ba1a”

const example1 = ('b' + 'a' + + 'a' + 'a').toLowerCase(); // 'banana' 
const example2 = ('b' + 'a' + + '1' + 'a').toLowerCase(); // 'ba1a'
console.log(example1);
console.log(example2);


9

Ten wiersz kodu ocenia wyrażenie, a następnie wywołuje metodę na podstawie zwróconej wartości.

Wyrażenie ('b' + 'a' + + 'a' + 'a')składa się wyłącznie z literałów łańcuchowych i operatorów dodawania.

  • Literały łańcuchowe „Literał łańcuchowy to zero lub więcej znaków ujętych w pojedyncze lub podwójne cudzysłowy”.
  • Operator dodawania (+) „Operator dodawania dokonuje konkatenacji łańcucha lub dodawania liczbowego”.

Podjęte działanie niejawne to wywołanie ToNumber w ciągu znaków

  • ToNumber zastosowany do typu ciągu „ToNumber zastosowany do ciągów stosuje gramatykę do wejściowego ciągu. Jeśli gramatyka nie może interpretować łańcucha jako rozwinięcia StringNumericLiteral, wówczas wynikiem ToNumber jest NaN.”

Interpretator ma zasady dotyczące parsowania wyrażenia, dzieląc je na składniki wyrażeń lewej i prawej ręki.


Krok 1: 'b' + 'a'

Lewe wyrażenie: 'b'
lewa Wartość: „b”

Operator: + (jedna ze stron wyrażenia jest łańcuchem, więc konkatenacja łańcucha)

Właściwe wyrażenie: 'a' właściwa wartość: „a”

Wynik: 'ba'


Krok 2: 'ba' + + 'a'

Lewe wyrażenie: 'ba'
lewe Wartość: „ba”

Operator: + (jedna ze stron wyrażenia jest łańcuchem, więc konkatenacja łańcucha)

Właściwe wyrażenie: + 'a'(ocenia wartość matematyczną znaku „a” przy założeniu, że jest to liczba dodatnia ze znaku + - znak minus również by tu działał, wskazując liczbę ujemną - co powoduje, że NaN)
Właściwa wartość: NaN (ponieważ operator jest konkatenacją łańcuchów, wywoływana jest taString dla tej wartości podczas konkatenacji)

Wynik: „baNaN”


Krok 3: 'baNaN' + 'a'

Lewe wyrażenie: 'baNaN'
lewe Wartość: „baNaN”

Operator: + (jedna ze stron wyrażenia jest łańcuchem, więc konkatenacja łańcucha)

Właściwe wyrażenie: 'a'
właściwa wartość: „a”

Wynik: „baNaNa”


Następnie zostało ocenione wyrażenie grupujące i wywoływane jest toLowerCase, co pozostawia nam banana.


7

Użycie + spowoduje konwersję dowolnej wartości na liczbę w JavaScript!

Więc...

Najważniejszą rzeczą, o której należy najpierw wiedzieć i uczyć się, jest użycie +przed jakąkolwiek wartością w JavaScript, przekształci tę wartość na liczbę , ale jeśli tej wartości nie można przekonwertować, silnik JavaScript zwróci NaN , co oznacza, że nie liczbę (nie można konwertować na liczbę, kolego!), a resztę historii jak poniżej:

Dlaczego wynik („b” + „a” + + „a” + „a”). ToLowerCase () „banana”?



0

Zobacz magię tutaj. Drugi plus to jednoargumentowy operator, który daje „NaN”

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.