ใน JavaScript คุณมักจะได้ยินว่าค่าดั้งเดิมนั้นไม่เปลี่ยนรูป ต่างจากค่าที่ไม่ใช่ค่าดั้งเดิมซึ่งคือ เปลี่ยนแปลงได้ สิ่งสำคัญคือต้องเข้าใจความแตกต่างระหว่างประเภทค่าเหล่านี้ (เรียกอีกอย่างว่า ประเภทข้อมูล ) เพราะจะช่วยให้คุณไม่ต้องปวดหัวมากมายระหว่างทาง
ค่าดั้งเดิมคือสิ่งที่ชอบ:
- ตัวเลข
- สตริง
- บูลีน
ค่าที่ไม่ใช่พื้นฐานคือ:
- วัตถุ
- ฟังก์ชัน
Mutable หมายความว่า สามารถ จะมีการเปลี่ยนแปลง
เปลี่ยนแปลงไม่ได้หมายความว่า ไม่สามารถ จะมีการเปลี่ยนแปลง
ค่าที่ไม่ใช่แบบพื้นฐานไม่สามารถเปลี่ยนแปลงได้
ต่อไปนี้คือรายการ (อาร์เรย์) ของคนที่กำหนดให้กับตัวแปร:
let peopleList = ['Arnold', 'Linda', 'Sylvester', 'Dolph']
ตอนนี้ฉันต้องการ กลายพันธุ์ รายการของฉัน. Mutate หมายถึง เปลี่ยนแปลง ฉันต้องการเปลี่ยน Arnold เป็น Jean-Claude และพิมพ์ผลลัพธ์:
let peopleList = ['Arnold', 'Linda', 'Sylvester', 'Dolph']
peopleList[0] = 'Jean-Claude'
console.log(peopleList)
มันได้ผล! เราเพิ่งทำการกลายพันธุ์ของค่าที่มีอยู่ ในกรณีนี้ ค่าที่มีอยู่คืออาร์เรย์ (รายการ) หรือโดยเฉพาะอย่างยิ่ง อ็อบเจ็กต์อาร์เรย์ .
ใน JavaScript ค่าที่ไม่ใช่แบบพื้นฐานจะเปลี่ยนแปลงได้ (เปลี่ยนแปลงได้)
ค่าดั้งเดิมจะไม่เปลี่ยนรูป
ต่อไปนี้เป็นค่าข้อความ (สตริง) ที่กำหนดให้กับตัวแปร:
let person = 'Ernold'
น่าเสียดายที่เราสะกด Arnold ผิดโดยใช้ E แทน A ในตัวอักษรตัวแรกของชื่อของเขา มาเปลี่ยนอย่างรวดเร็วและพิมพ์ผลลัพธ์:
let person = 'Ernold'
person[0] = 'A'
console.log(person) // output: Ernold
รออะไร? ทำไมถึงพิมพ์ว่า “เออร์โนลด์”? เราไม่ได้แค่สลับ E กับ A!?
ไม่ เพราะค่าที่เราพยายามจะกลายพันธุ์คือ สตริง ซึ่งเป็น ค่าดั้งเดิม — และค่าดั้งเดิมทั้งหมดจะไม่เปลี่ยนรูป (ไม่เปลี่ยนแปลง)
เฉพาะค่าที่ไม่ใช่ค่าพื้นฐาน (อ็อบเจกต์ &ฟังก์ชัน) เท่านั้นที่จะเปลี่ยนแปลงได้
สับสน?
เป็นเรื่องปกติโดยสิ้นเชิงที่จะสับสนเกี่ยวกับสิ่งนี้ในช่วงเริ่มต้นของเส้นทางการเรียนรู้ JavaScript เพราะตัวอย่างด้านบนมีหน้าตาและพฤติกรรมคล้ายกัน — ใน บางส่วน สถานการณ์ต่างๆ
มาพิมพ์ชื่อจาก array . ของเรากัน จากก่อนหน้านี้:
let peopleList = ['Arnold', 'Linda', 'Sylvester', 'Dolph']
console.log(peopleList[0]) // output: "Arnold"
ไม่แปลกใจเลยที่มันพิมพ์ "Arnold"
.
ตอนนี้ มาพิมพ์อักษรตัวแรก สตริง . ของเรา จากตอนที่แล้ว (ชื่อสะกดผิด):
let person = 'Ernold'
console.log(person[0]) // output: ??
คุณคิดว่าจะเกิดอะไรขึ้น?
...
...
มันได้ผล! มันพิมพ์ "E"
!
คุณคาดหวังว่าสิ่งข้างต้นจะไม่ทำงานหรือไม่?
ไม่ว่าจะด้วยวิธีใด บทเรียนสำคัญที่นี่คือคุณสามารถเข้าถึง .ได้ ค่าดั้งเดิมในลักษณะเดียวกับที่คุณเข้าถึงค่าที่ไม่ใช่ค่าดั้งเดิม แต่คุณไม่สามารถเปลี่ยนแปลง (เปลี่ยนแปลง) ได้ นั่นคือความแตกต่างใหญ่ (การเข้าถึงกับการกลายพันธุ์)
ใน JavaScript ค่าดั้งเดิมคือ อ่านอย่างเดียว ในขณะที่ค่าที่ไม่ใช่พื้นฐาน (อ็อบเจ็กต์/อาร์เรย์, ฟังก์ชัน) เป็นทั้ง อ่านและเขียน
นั่นเป็นเหตุผลที่เราสามารถเปลี่ยน (กลายพันธุ์) ค่ารายการแรกของอาร์เรย์ของเราจาก Arnold
ถึง Jean-Claude
ก่อนหน้านี้ แต่เราไม่สามารถแก้ไขข้อผิดพลาดการสะกดคำง่ายๆ จาก "Ernold"
ถึง "Arnold"
— เนื่องจากเป็นสตริง และค่าสตริง/ค่าดั้งเดิมจะไม่เปลี่ยนแปลง
ตัวแปรเทียบกับค่า
(ฉันรู้ว่าพวกคุณคิดอะไรอยู่)
แม้ว่าเราจะสรุปได้ว่าค่าดั้งเดิมนั้นไม่สามารถเปลี่ยนแปลงได้ แต่ฉันก็ยังมุ่งมั่นที่จะแก้ไขข้อผิดพลาดในการสะกดคำว่า "Ernold" มาลองของใหม่กันเถอะ!
ดูโค้ดต่อไปนี้ (อ่านอย่างระมัดระวัง):
let person = 'Ernold'
person = 'Arnold'
console.log(person) // output: ??
เมื่อพิจารณาถึงสิ่งที่คุณได้เรียนรู้เกี่ยวกับค่าดั้งเดิม เช่น สตริง คุณคิดว่าข้อความข้างต้นจะพิมพ์ Arnold
ออกมาหรือไม่ , ใช่หรือไม่?
...
(ลองคิดดู)
...
มันพิมพ์ Arnold
!
พวกคุณบางคนรู้แล้วว่าเพราะอะไร แต่ถ้าคุณไม่รู้ นั่นเป็นเรื่องปกติ คุณจะได้สัมผัสกับ "อาฮ่า" ในช่วงเวลาหนึ่ง อ่านย่อหน้าต่อไปนี้อย่างระมัดระวัง
โค้ดด้านบนใช้งานได้เพราะเราไม่ได้เปลี่ยนค่าสตริง เราไม่ได้แตะต้องมันด้วยซ้ำ แต่เรากำลังมอบหมาย ใหม่ ค่าสตริงที่เรียกว่า 'Arnold'
ถึง person
ตัวแปรจึงไม่อ้างอิง (ชี้ไปที่) 'Ernold'
. อีกต่อไป ค่าสตริง.
ค่าดั้งเดิมเปลี่ยนแปลงไม่ได้ แต่ตัวแปรเปลี่ยนได้!
ตัวแปรไม่ใช่ค่า ดังนั้นกฎของความเปลี่ยนแปลงหรือความไม่เปลี่ยนรูปจึงไม่เหมือนกัน ตัวแปรชี้ไปที่ค่าเท่านั้น
เราไม่เคยแตะค่าสตริงเดิม 'Ernold'
โดยตรง เราเพิ่งบอก person
. ของเรา ตัวแปรให้ชี้ไปที่สตริงอื่นที่เรียกว่า 'Arnold'
แล้วใช้ console.log()
เพื่อพิมพ์ผลลัพธ์ออกมา
บางท่านอาจคิดว่าฉันกำลังเอาชนะม้าที่ตายแล้วที่นี่ แต่สิ่งสำคัญคือคุณต้องตระหนักรู้เกี่ยวกับวิธีการทำงานของ JavaScript การทำซ้ำคือเพื่อนของคุณ
หมายเหตุ:ประเภทของตัวแปรที่เราใช้ตลอดบทช่วยสอนนี้เป็นประเภทคีย์เวิร์ด let
— ซึ่งเปลี่ยนแปลงได้ ดังที่คุณเห็นในตัวอย่างโค้ดก่อนหน้านี้ หากเราใช้ const
ตัวแปร สถานการณ์จะแตกต่างกัน — แต่ฉันจะบันทึกหัวข้อนั้นสำหรับบทช่วยสอนอื่น
โดยสรุป:
ใน JavaScript:
- ค่าที่ไม่ใช่ค่าดั้งเดิมสามารถอ้างถึง เข้าถึง และกลายพันธุ์ได้
- ค่าดั้งเดิมสามารถอ้างถึง เข้าถึงได้ แต่ ไม่ถูกกลายพันธุ์
- ตัวแปรและค่าเป็นสองสิ่งที่แตกต่างกัน ใช้กฎที่แตกต่างกัน