ทำไมผลลัพธ์ของ ('b' + 'a' + + 'a' + 'a') toLowerCase () 'Banana'


575

ฉันฝึก JavaScript เมื่อเพื่อนของฉันคนหนึ่งเจอรหัส JavaScript นี้:

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

คำตอบรหัสข้างต้น"banana"! มีใครอธิบายได้บ้างไหม


22
ที่สองบวกเป็นผู้ดำเนินการเอกภาค: คือ+"a" NaN
Gerardo Furtado

8
ในคอนโซลเขียน+'a'ด้วยตัวเองและดูว่าเกิดอะไรขึ้น
โปรแกรมเมอร์บางคนเพื่อน

23
และสำหรับผู้ที่กระตือรือร้นมากขึ้น ดูรายการความสนุกแบบเต็ม
Giddy Naya

4
มีความเกี่ยวข้องอย่างยิ่ง: stackoverflow.com/q/9032856
Kyll

คำตอบ:


566

+'a'แก้ไขเป็นNaN("ไม่ใช่ตัวเลข") เพราะมันจะรวมสตริงกับตัวเลขในขณะที่อักขระaไม่สามารถแยกเป็นตัวเลขได้

document.write(+'a');
bananaเป็นตัวพิมพ์เล็กมันจะกลายเป็น

เพิ่มNaNการ"ba"ผลัดกันNaNเข้าไปในสตริงเนื่องจากการพิมพ์การแปลงให้"NaN" baNaNและแล้วเราก็เป็นเบื้องหลังให้abaNaNa

ช่องว่างระหว่าง+ +คือการทำให้การเรียงต่อกันของสตริงแรกและที่สองเป็นตัวดำเนินการบวกและบวก (เช่น "บวก") คุณมีผลลัพธ์เหมือนกันถ้าคุณใช้'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'เป็นตัวเลขที่ใช้ประกอบการบวกเอก เนื่องจาก'a'ไม่ใช่ตัวเลขผลลัพธ์คือNaN ( "Not-A-Number" ):

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

แม้ว่าNaNย่อมาจาก "ไม่ได้เป็นจำนวน" ก็ยังคงเป็นตัวเลขประเภท ; เมื่อเพิ่มเข้าไปในสตริงมันจะเชื่อมโยงกับหมายเลขอื่น ๆ :

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

ในที่สุดก็ลดระดับ:

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

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

เพื่อความชัดเจนลองแบ่งมันออกเป็นสองขั้นตอน อันดับแรกเราจะได้รับค่าของนิพจน์ที่มีวงเล็บแล้วจากนั้นเราใช้toLowerCase()ฟังก์ชันกับผลลัพธ์

ขั้นตอนแรก

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

ไปLRเรามี:

  • 'b' + 'a'ส่งกลับbaนี่คือการต่อข้อมูลแบบปกติ
  • ba + + 'a'ความพยายามที่จะ concatenate บริติชแอร์เวย์+ 'a'ด้วย อย่างไรก็ตามเนื่องจากตัวดำเนินการยูนารี+พยายามแปลงตัวถูกดำเนินการเป็นตัวเลขค่าNaNจะถูกส่งกลับซึ่งจะถูกแปลงเป็นสตริงเมื่อทำการต่อกับbaดั้งเดิมซึ่งทำให้baNaNเกิดขึ้น
  • baNaN+ 'a' ผลตอบแทนกล้วย นี่เป็นการต่อแบบปกติ

ในขั้นตอนนี้ผลจากขั้นตอนที่หนึ่งคือกล้วย

ขั้นตอนที่สอง

การใช้.toLowerCase()ค่าที่ส่งคืนจากขั้นตอนที่หนึ่งจะให้:

กล้วย

มีการเล่นคล้ายกันใน 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')ประกอบด้วยตัวอักษรสตริงและผู้ประกอบการเพิ่ม

การกระทำที่เกิดขึ้นโดยนัยคือการเรียก ToNumber บนสตริง

  • ToNumberนำไปใช้กับชนิดสตริง "ToNumber นำไปใช้กับ Strings ใช้ไวยากรณ์กับอินพุตสตริงหากไวยากรณ์ไม่สามารถตีความสตริงเป็นส่วนขยายของ 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

การใช้ + จะแปลงค่าใด ๆ ให้เป็น Number ใน JavaScript!

ดังนั้น...

สิ่งสำคัญที่ต้องรู้ก่อนและเรียนรู้จากการใช้+ก่อนค่าใด ๆ ใน JavaScript จะแปลงค่านั้นเป็นตัวเลขแต่ถ้าค่านั้นไม่สามารถแปลงได้เครื่องยนต์ JavaScript จะคืนNaNซึ่งหมายความว่าไม่ใช่ตัวเลข (ไม่สามารถ ถูกแปลงเป็นตัวเลขเพื่อน!) และส่วนที่เหลือของเรื่องดังต่อไปนี้:

ทำไมผลลัพธ์ของ ('b' + 'a' + + 'a' + 'a') toLowerCase () 'Banana'



0

ดูเวทย์มนตร์ที่นี่ สิ่งที่สองบวกเป็นตัวดำเนินการเอกที่ให้ 'น่าน'

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.