javascript - Varför är resultatet av ('b'+'a'+ + 'a' + 'a').toLowerCase() 'banana'?
Jag övade på lite JavaScript när en av mina vänner stötte på denna JavaScript-kod:
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());Koden ovan svarar "banana"! Kan någon förklara varför?
Svar #1
+'a' resulterar i NaN ("Inte ett tal") eftersom det omvandlar en sträng till ett tal, medan tecknet a inte kan tolkas som ett tal.
document.write(+'a');I gemener blir det nan.
Att lägga till NaN till "ba" omvandlar NaN till strängen "NaN" på grund av typkonvertering, vilket ger baNaN. Och sedan finns det ett a bakom, vilket ger baNaNa.
Mellanrummet mellan + + är för att göra den första till strängkonkatenering och den andra till en unär plus (dvs. "positiv") operator. Du får samma resultat om du använder 'ba'+(+'a')+'a', löst som 'ba'+NaN+'a', vilket är ekvivalent med 'ba'+'NaN'+'a' på grund av typomvandling.
document.write('ba'+(+'a')+'a');Svar #2
'b' + 'a' + + 'a' + 'a'
...utvärderas som...
'b' + 'a' + (+'a') + 'a'
(se: operatorns prioritetsordning)
(+'a') försöker omvandla 'a' till ett nummer med hjälp av den unära plusteckensoperatorn. Eftersom 'a' inte är ett nummer blir resultatet NaN ("Inte ett nummer"):
'b' + 'a' + NaN + 'a'
Även om NaN står för "Not a Number", är det fortfarande en numerisk typ; när det läggs till strängar, konkatenerar det precis som vilket annat nummer som helst:
'b' + 'a' + NaN + 'a' => 'baNaNa'
Slutligen är det med gemener:
'baNaNa'.toLowerCase() => 'banana'
Svar #3
('b' + 'a' + + 'a' + 'a').toLowerCase()
För tydlighetens skull, låt oss bryta ned detta i två steg. Först får vi värdet av det uttryck som står inom parentes och sedan tillämpar vi toLowerCase()-funktionen på resultatet.
Steg ett
'b' + 'a' + + 'a' + 'a'
Går V-H, har vi:
'b' + 'a'returnerar ba, detta är vanlig sammanfogning.ba + + 'a'försöker sammanfoga ba med+ 'a'. Eftersom den unära operatorn+försöker omvandla sin operand till ett tal returneras värdet NaN, vilket sedan omvandlas till en sträng när det sammanfogas med det ursprungliga ba - vilket resulterar i baNaN.baNaN+ 'a' returnerar baNaNa. Återigen, detta är vanlig sammanfogning.
I detta skede är resultatet från steg ett baNaNa.
Steg två
Att använda .toLowerCase() på värdet som returnerades från steg ett ger:
banan
Det finns många liknande ordvitsar i JavaScript som du kan kolla in.
Svar #4
Det är bara på grund av +-operatorn.
Vi kan få ytterligare kunskap från att dela upp det.
=> ( ('b') + ('a') + (++) + ('a') + ('a'))
=> ( ('b') + ('a') + (+) + ('a') + ('a')) // Here + + convert it to +operator
Which later on try to convert next character to the number.
Till exempel
const string = '10';
Du kan omvandla en sträng till ett tal på 2 sätt:
- Number(string);
- +string;
Så tillbaka till den ursprungliga frågan; Här försöker den konvertera nästa tecken ('a') till ett tal men plötsligt fick vi felet NaN,
( ('b') + ('a') + (+'a') + ('a'))
( ('b') + ('a') + NaN + ('a'))
Men det behandlas som en sträng eftersom det föregående tecknet var i strängen. Så det kommer att vara
( ('b') + ('a') + 'NaN' + ('a'))
Och slutligen konverterar det till toLowerCase(), så det skulle bli banana
Om du sätter ett nummer bredvid det, kommer ditt resultat att förändras.
( 'b' + 'a' + + '1' + 'a' )
Det skulle vara 'ba1a'
const example1 = ('b' + 'a' + + 'a' + 'a').toLowerCase(); // 'banana'
const example2 = ('b' + 'a' + + '1' + 'a').toLowerCase(); // 'ba1a'
console.log(example1);
console.log(example2);Svar #5
Denna kodrad utvärderar ett uttryck och anropar sedan en metod baserat på det returnerade värdet.
Uttrycket ('b' + 'a' + + 'a' + 'a') består enbart av strängliteraler och additionsoperatorer.
- Strängliteraler "En strängliteral är noll eller fler tecken omslutna av enkla eller dubbla citattecken."
- Additionoperatorn ( + ) "Additionoperatorn utför antingen strängsammanfogning eller numerisk addition."
En implicit åtgärd som tas är anropet av ToNumber på en sträng
- ToNumber tillämpat på strängtypen "ToNumber tillämpat på strängar tillämpar grammatiken på inmatningssträngen. Om grammatiken inte kan tolka strängen som en utvidgning av StringNumericLiteral, blir resultatet av ToNumber NaN."
Tolkaren har regler för hur man analyserar uttrycket, genom att bryta ner det i dess komponenter av vänster- och högerhanduttryck.
Steg 1: 'b' + 'a'
Vänster uttryck: 'b'
Vänster värde: 'b'
Operator: + (en av uttryckssidorna är en sträng, så strängkonkatenering)
Rätt uttryck: 'a' Rätt värde: 'a'
Resultat: 'ba'
Steg 2: 'ba' + + 'a'
Vänsteruttryck: 'ba'
Vänstervärde: 'ba'
Operator: + (en av uttryckssidorna är en sträng, så strängkonkatenering)
Rätt uttryck: + 'a' (detta beräknar det matematiska värdet av tecknet 'a' under antagandet att det är ett positivt tal från + tecknet -- minustecknet skulle också ha fungerat här och indikerat ett negativt tal -- vilket resulterar i NaN)
Rätt värde: NaN (eftersom operatorn är strängkonkatenering, anropas toString på detta värde under konkateneringen)
Resultat: 'baNaN'
Steg 3: 'baNaN' + 'a'
Vänster uttryck: 'baNaN'
Vänster värde: 'baNaN'
Operator: + (en av uttryckssidorna är en sträng, så strängkonkatenering)
Rätt uttryck: 'a'
Rätt värde: 'a'
Resultat: 'baNaNa'
Efter detta har grupputtrycket utvärderats, och toLowerCase kallas vilket lämnar oss med banana.
Svar #6
Att använda + kommer att konvertera vilket värde som helst till Number i JavaScript!
Så...
Det viktigaste att först veta och lära sig här är att använda + framför ett värde i JavaScript, kommer att konvertera det värdet till ett nummer, men om det värdet inte kan konverteras, kommer JavaScript-motorn att returnera NaN, vilket betyder inte ett nummer (kan inte konverteras till ett nummer, kompis!) och resten av historien är som nedan:
