มีการข่มขู่ในโลก JavaScript - เรื่องราวนักสืบ
นาธานคุณไม่รู้หรอกว่าคุณค้นพบอะไร
ฉันได้ตรวจสอบเรื่องนี้มาหลายสัปดาห์แล้ว ทุกอย่างเริ่มต้นในคืนที่มีพายุเมื่อเดือนตุลาคมที่ผ่านมา ฉันบังเอิญเข้าNumberชั้นเรียน - ฉันหมายความว่าทำไม JavaScript ถึงมีNumberระดับโลก?
ฉันไม่ได้เตรียมตัวสำหรับสิ่งที่ฉันจะค้นหาต่อไป
ปรากฎว่า JavaScript โดยไม่บอกคุณได้เปลี่ยนหมายเลขของคุณเป็นวัตถุและวัตถุของคุณเป็นตัวเลขภายใต้จมูกของคุณ
จาวาสคริปต์กำลังหวังว่าจะไม่มีใครจับ แต่คนได้รับการรายงานพฤติกรรมที่ไม่คาดคิดที่แปลกและตอนนี้ขอบคุณคุณและคำถามของคุณฉันมีหลักฐานที่ฉันต้องระเบิดสิ่งนี้เปิดกว้าง
นี่คือสิ่งที่เราค้นพบ ฉันไม่รู้ว่าฉันควรจะบอกเรื่องนี้กับคุณหรือไม่ - คุณอาจต้องการปิดจาวาสคริปต์ของคุณ
> function dis() { return this }
undefined
เมื่อคุณสร้างฟังก์ชั่นนั้นคุณอาจไม่รู้เลยว่าจะเกิดอะไรขึ้นต่อไป ทุกอย่างดูดีและทุกอย่างเรียบร้อยดี - ตอนนี้
ไม่มีข้อความแสดงข้อผิดพลาดเพียงแค่คำว่า "undefined" ในเอาต์พุตคอนโซลสิ่งที่คุณคาดหวัง ท้ายที่สุดนี่เป็นการประกาศฟังก์ชั่น - มันไม่ควรจะคืนอะไรเลย
แต่นี่เป็นเพียงจุดเริ่มต้น เกิดอะไรขึ้นต่อไปไม่มีใครสามารถทำนายได้
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
ใช่ฉันรู้คุณคาดหวัง5แต่นั่นไม่ใช่สิ่งที่คุณได้รับมัน - คุณมีอย่างอื่น - สิ่งที่แตกต่าง
สิ่งเดียวกันเกิดขึ้นกับฉัน
ฉันไม่รู้จะทำยังไง มันทำให้ฉันถั่ว ฉันนอนไม่หลับฉันกินไม่ได้ฉันพยายามที่จะดื่ม แต่ไม่มี Mountain Dew ที่จะทำให้ฉันลืม มันไม่สมเหตุสมผลเลย!
นั่นคือตอนที่ฉันรู้ว่าเกิดอะไรขึ้นจริง ๆ - มันเป็นการบีบบังคับและมันเกิดขึ้นตรงนั้นต่อหน้าต่อตาของฉัน แต่ฉันก็ตาบอดเกินกว่าจะมองเห็นได้
Mozilla พยายามที่จะฝังมันโดยการวางไว้ในที่ที่พวกเขารู้ว่าไม่มีใครจะมอง - พวกเขาเอกสาร
หลังจากชั่วโมงของการอ่านซ้ำและการอ่านซ้ำและการอ่านซ้ำฉันพบสิ่งนี้:
"... และค่าดั้งเดิมจะถูกแปลงเป็นวัตถุ"
มันก็ธรรมดาตรงที่สามารถสะกดได้ด้วยฟอนต์ Open Sans มันเป็นcall()ฟังก์ชั่น - ฉันจะโง่ได้ยังไง!
หมายเลขของฉันไม่ใช่หมายเลขอีกต่อไป เมื่อฉันผ่านมันไปcall()มันกลายเป็นอย่างอื่น มันกลายเป็น ... วัตถุ
ตอนแรกฉันไม่อยากจะเชื่อเลย สิ่งนี้จะเป็นจริงได้อย่างไร? แต่ฉันไม่สามารถเพิกเฉยต่อหลักฐานที่มีอยู่รอบตัวฉัน มันอยู่ที่นั่นถ้าคุณเพิ่งดู:
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
wtfถูกต้อง ตัวเลขไม่สามารถมีคุณสมบัติที่กำหนดเองได้ - เราทุกคนรู้ว่า! มันเป็นสิ่งแรกที่พวกเขาสอนคุณที่สถานศึกษา
เราควรรู้ทันทีที่เห็นคอนโซลเอาท์พุท - นี่ไม่ใช่ตัวเลขที่เราคิดว่ามันเป็น นี่คือนักต้มตุ๋น - วัตถุผ่านตัวมันเองไปตามหมายเลขบริสุทธิ์ที่ไร้เดียงสาของเรา
นี่คือ new Number(5)...
แน่นอน! มันทำให้รู้สึกที่สมบูรณ์แบบ call()มีงานต้องทำเขาต้องเรียกใช้ฟังก์ชั่นและเพื่อทำสิ่งที่เขาต้องการในการเติมthisเขารู้ว่าเขาไม่สามารถทำได้ด้วยตัวเลข - เขาต้องการวัตถุและเขาก็เต็มใจทำทุกอย่างเพื่อให้ได้มาด้วยซ้ำ ถ้านั่นหมายถึงการบังคับหมายเลขของเรา เมื่อcall()เห็นตัวเลข5เขาเห็นโอกาส
มันเป็นแผนการที่สมบูรณ์แบบ: รอจนกว่าจะไม่มีใครดูและสลับหมายเลขของเราเพื่อหาวัตถุที่มีลักษณะเหมือนมัน เราได้จำนวนฟังก์ชั่นจะถูกเรียกใช้และไม่มีใครฉลาดกว่า
มันเป็นแผนที่สมบูรณ์แบบจริงๆ แต่ก็เหมือนกับทุกแผนแม้แต่แผนการที่สมบูรณ์แบบมีช่องโหว่อยู่ในนั้นและเรากำลังจะตกลงไป
ดูสิสิ่งที่call()ไม่เข้าใจคือเขาไม่ใช่คนเดียวในเมืองที่สามารถบีบบังคับตัวเลขได้ นี่คือ JavaScript หลังจากทั้งหมด - การบีบบังคับอยู่ทุกที่
call() รับหมายเลขของฉันและฉันจะไม่หยุดจนกว่าฉันจะดึงหน้ากากออกมาจากนักต้มตุ๋นตัวน้อยของเขาและเปิดเผยให้เขาเห็นในชุมชน Stack Overflow ทั้งหมด
แต่อย่างไร ฉันต้องการแผน แน่ใจว่ามันดูเหมือนตัวเลข แต่ฉันรู้ว่ามันไม่ใช่มีวิธีที่จะพิสูจน์ได้ว่า แค่นั้นแหละ! มันมีลักษณะเช่นจำนวน แต่มันสามารถทำหน้าที่เช่นเดียว?
ฉันบอกว่าfiveฉันต้องการให้เขาใหญ่ขึ้น 5 เท่า - เขาไม่ได้ถามทำไมและฉันไม่ได้อธิบาย ฉันทำสิ่งที่โปรแกรมเมอร์ดี ๆ จะทำ: ฉันทวีคูณ แน่นอนว่าไม่มีทางที่เขาจะปลอมแปลงออกจากสิ่งนี้ได้
> five * 5
25
> five.wtf
'potato'
บ้ามัน! ไม่เพียงfiveแค่ทวีคูณwtfก็ยังอยู่ที่นั่น ประณามชายผู้นี้และมันฝรั่งของเขา
เกิดอะไรขึ้น? ฉันผิดเกี่ยวกับเรื่องทั้งหมดนี้เหรอ? คือfiveจริงๆเป็นจำนวนมาก? ไม่ฉันต้องคิดถึงบางสิ่งบางอย่างฉันรู้ว่ามีบางสิ่งที่ฉันต้องลืมบางสิ่งที่เรียบง่ายและเรียบง่ายที่ฉันมองข้ามไป
นี่ไม่ได้ดูดีเลยฉันเขียนคำตอบนี้หลายชั่วโมงและฉันก็ยังไม่เข้าใกล้ประเด็น ฉันไม่สามารถติดตามเรื่องนี้ได้ในที่สุดผู้คนจะหยุดอ่านฉันต้องคิดถึงบางสิ่งและฉันต้องคิดให้เร็ว
เดี๋ยวก่อน! fiveไม่ใช่ 25, 25 คือผลลัพธ์ 25 เป็นตัวเลขที่แตกต่างอย่างสิ้นเชิง แน่นอนฉันจะลืมได้อย่างไร ตัวเลขไม่เปลี่ยนรูป เมื่อคุณคูณไม่มีอะไรได้รับมอบหมายให้สิ่งที่คุณเพียงแค่สร้างหมายเลขใหม่5 * 525
นั่นต้องเป็นสิ่งที่เกิดขึ้นที่นี่ อย่างใดเมื่อฉันคูณfive * 5, fiveจะต้องได้รับการบังคับให้จำนวนและตัวเลขที่ต้องเป็นหนึ่งที่ใช้สำหรับการคูณ มันเป็นผลลัพธ์ของการคูณที่ได้รับการพิมพ์ไปยังคอนโซลไม่ใช่คุณค่าของfiveตัวมันเอง fiveไม่เคยได้รับมอบหมายอะไรเลยแน่นอนว่ามันจะไม่เปลี่ยนแปลง
ดังนั้นฉันfiveจะกำหนดผลของการผ่าตัดได้อย่างไร ฉันเข้าใจแล้ว. fiveแม้กระทั่งก่อนที่จะมีโอกาสคิดผมก็ตะโกน "++"
> five++
5
Aha! ฉันมีเขา! ทุกคนรู้5 + 1คือ6นี่เป็นหลักฐานที่ฉันต้องการที่จะเปิดเผยว่าfiveไม่ได้เป็นจำนวนมาก! มันเป็นนักต้มตุ๋น! นักต้มตุ๋นที่ไม่ดีที่ไม่รู้วิธีนับ และฉันสามารถพิสูจน์ได้ นี่คือวิธีการทำงานของจำนวนจริง:
> num = 5
5
> num++
5
รอ? เกิดอะไรขึ้นที่นี่? ถอนหายใจฉันรู้สึกอึดอัดใจจนfiveลืมว่าผู้ให้บริการโพสต์ทำงานอย่างไร เมื่อผมใช้++ในตอนท้ายของฉันบอกว่าผลตอบแทนคุ้มค่าในปัจจุบันเพิ่มขึ้นแล้วfive fiveมันคือค่าก่อนที่จะมีการดำเนินการที่ได้รับการพิมพ์ไปยังคอนโซล numเป็นจริง6และฉันสามารถพิสูจน์ได้:
>num
6
ได้เวลาดูสิ่งที่fiveเป็นจริง:
>five
6
... มันเป็นสิ่งที่ควรจะเป็น fiveดี - แต่ฉันดีกว่า หากfiveยังคงเป็นวัตถุที่จะหมายความว่ามันจะยังคงมีคุณสมบัติwtfและฉันก็ยินดีที่จะเดิมพันทุกอย่างที่มันไม่ได้
> five.wtf
undefined
Aha! ฉันถูก. ฉันมีเขา! fiveตอนนี้เป็นจำนวน - มันไม่ใช่วัตถุอีกต่อไป ฉันรู้ว่าเทคนิคการคูณจะไม่ช่วยในครั้งนี้ ดูมันfive++ five = five + 1ซึ่งแตกต่างจากการคูณที่ผู้ประกอบการกำหนดค่าให้กับ++ fiveโดยเฉพาะอย่างยิ่งจะกำหนดผลของการfive + 1ที่เช่นเดียวกับในกรณีของการคูณผลตอบแทนไม่เปลี่ยนรูปใหม่จำนวน
ฉันรู้ว่าฉันมีเขาและเพียงเพื่อให้แน่ใจว่าเขาไม่สามารถดิ้นรนออกจากมัน ฉันได้ทดสอบแขนเสื้อของฉันอีกครั้ง ถ้าฉันพูดถูกและfiveเป็นจำนวนมากตอนนี้สิ่งนี้จะไม่ทำงาน:
> five.wtf = 'potato?'
'potato?'
เขาจะไม่หลอกฉันในครั้งนี้ ฉันรู้ว่าpotato?กำลังจะถูกพิมพ์ไปที่คอนโซลเพราะนั่นเป็นผลลัพธ์ของการมอบหมาย คำถามที่แท้จริงคือจะwtfยังคงอยู่หรือไม่
> five.wtf
undefined
อย่างที่ฉันสงสัย - ไม่มี - เพราะตัวเลขไม่สามารถกำหนดคุณสมบัติได้ เราเรียนรู้ว่าปีแรกที่สถาบันการศึกษา;)
ขอบคุณนาธาน ต้องขอบคุณความกล้าของคุณในการถามคำถามนี้ในที่สุดฉันก็สามารถนำเรื่องทั้งหมดนี้มาไว้ข้างหลังฉันและไปยังคดีใหม่
toValue()เหมือนหนึ่งที่เกี่ยวกับฟังก์ชั่นนี้ โอ้พระเจ้าที่รัก Nooo!
++ดูเหมือนว่าจะส่งผลกระทบต่อชนิดพื้นฐาน