ทำไมประเภทของ“ วัตถุ” ที่เป็นโมฆะ?


242

ฉันกำลังอ่าน 'จาวาสคริปต์ระดับมืออาชีพสำหรับนักพัฒนาเว็บ' บทที่ 4 และมันบอกฉันว่าสิ่งพื้นฐานห้าประเภทคือ: ไม่ได้กำหนดไว้เป็นโมฆะบูลีนตัวเลขและสตริง

ถ้าnullเป็นดึกดำบรรพ์ทำไมถึงtypeof(null)กลับมา"object"?

นั่นไม่ได้หมายความว่าnullจะถูกส่งผ่านโดยการอ้างอิง (ฉันสมมติว่าที่นี่วัตถุทั้งหมดจะถูกส่งผ่านโดยอ้างอิง) จึงทำให้มันไม่ได้เป็นแบบดั้งเดิม?


50
คำตอบ: เพราะสเป็คบอกอย่างนั้น โดยทั่วไปถือว่าเป็นความผิดพลาด
SLAK

5
หมายเหตุ typeof เป็นโอเปอเรเตอร์ไม่ใช่ฟังก์ชั่น (และอันที่จริงคุณสามารถละเว้นวงเล็บในสิ่งที่เกิดขึ้นหลังจากนั้น) ดังนั้นจึงไม่มีความเหมาะสมที่จะพูดคุยเกี่ยวกับการส่งผ่านโดยการอ้างอิงที่นี่ หนังสือ "JavaScript: The Good Parts" กล่าวถึงข้อเท็จจริงที่ว่า typeof null === 'object' ในส่วน A.6 ของภาคผนวก A ที่มีชื่อว่า 'Awful Parts'
John Sonderson

5
ฉันคิดว่าฉันต้องการอ่าน 'Awful Parts' hah
austinheiman

1
ความผิดพลาดครั้งใหญ่ :)
Alexander Mills

2
ดังนั้นสิ่งที่เราควรใช้แทน typeof เพื่อตรวจสอบชนิดของค่าที่ตัวแปรถือ? ฉันชอบที่จะรู้ว่ามันคืออะไร (บูลีน, สตริง, จำนวน, อาร์เรย์, วัตถุ, ฟังก์ชั่น, สัญลักษณ์, null, ไม่ได้กำหนด NaN)
Costa

คำตอบ:


219

จากหน้า MDN เกี่ยวกับพฤติกรรมของtypeofผู้ประกอบการ :

null

// นี่คือจุดเริ่มต้นของ JavaScript
typeof null === 'วัตถุ';

ในการใช้งาน JavaScript ครั้งแรกค่า JavaScript ถูกแสดงเป็นแท็กประเภทและค่า แท็กประเภทสำหรับวัตถุคือ 0 nullถูกแสดงเป็นตัวชี้ NULL (0x00 ในแพลตฟอร์มส่วนใหญ่) ดังนั้น null มี 0 เป็นแท็กประเภทดังนั้นtypeofค่าส่งคืน"วัตถุ" ( อ้างอิง )

การแก้ไขที่ถูกเสนอสำหรับ ECMAScript (ผ่านเลือกใน) แต่ได้รับการปฏิเสธ typeof null === 'null'มันจะมีผลในการ


138
เป็นเรื่องน่าเสียดายที่การเปลี่ยนแปลงครั้งนี้ไม่ได้ทำให้อยู่ในโหมดเข้มงวดอย่างน้อย ...
Ingo Bürk

ผู้คนได้รับประโยชน์จากการเล่นโวหารและรหัสจำนวนมากจะต้องมีการเปลี่ยนแปลงหากสิ่งนี้ไม่ได้ถูกปฏิเสธฉันเดา
Cold Cerberus

มันสมเหตุสมผลกว่าสำหรับคนที่มีชีวิตไม่กี่คนที่ต้องการให้สิ่งนี้เปลี่ยนรหัสของพวกเขามากกว่านักพัฒนาที่เหลือในช่วงเวลาที่เหลือเพื่อเรียนรู้ เพียงเพราะคนยังไม่มีตัวตนไม่ได้หมายความว่าพวกเขาไม่สำคัญก็แค่หมายความว่าพวกเขาไม่มีที่พึ่ง
Seph Reed

ไม่สมเหตุสมผลว่าทำไมคนถึงใช้นี่เป็นเช็คว่าง มันไม่สมเหตุสมผลเลยทำไมพวกเขาถึงใช้มัน? ไม่สามารถเพิ่มการเปลี่ยนแปลงได้เนื่องจากการเข้ารหัสไม่ดี
Emobe

69

ถ้าnullเป็นดึกดำบรรพ์ทำไมถึงtypeof(null)กลับมา"object"?

เพราะสเป็คบอกอย่างนั้น

11.4.3typeofผู้ประกอบการ

การผลิตUnaryExpression : typeof UnaryExpressionได้รับการประเมินดังนี้:

  1. ให้Valเป็นผลมาจากการประเมินUnaryExpression
  2. ถ้าประเภท ( Val ) เป็นเอกสารอ้างอิงแล้ว
       ถ้าIsUnresolvableReference ( val ) เป็นจริงให้ส่งคืน " undefined"
       ข ให้valเป็นGetValue ( val )
  3. ส่งคืนสตริงที่กำหนดโดยType ( val ) ตามตาราง 20

ป้อนคำอธิบายรูปภาพที่นี่


@peter ไม่typeofบอกคุณว่าคุณสามารถโทรหาวิธีการกับบางสิ่งได้หรือไม่
แมตต์บอล

2
ความรู้ของฉันคุณสามารถโทรหาวิธีการในสิ่งอื่นที่ไม่ใช่และnull undefined
Matt Ball

4
@peter คุณไม่สามารถเรียกใช้เมธอดบน string primitive ได้ แต่ต้องขอบคุณสตริง primitives (และจำนวน primitives และ boolean primitives) โดยปริยายและ "auto-boxed" โดยอัตโนมัติใน String, Number และ Boolean wrappers เมื่อคุณใช้หนึ่งใน primitives ที่มีคุณสมบัติ ผู้ประกอบการอ้างอิง ( .หรือ[ ])
Pointy

28

ดังที่ระบุไว้สเป็คพูดอย่างนั้น แต่เนื่องจากการใช้งานจาวาสคริปต์นั้นทำให้เกิดการเขียนข้อมูลจำเพาะของ ECMAScript และสเปคนั้นระวังที่จะไม่แก้ไขข้อผิดพลาดในการนำไปใช้งานครั้งแรกจึงยังคงมีคำถามที่ถูกต้อง ดักลาส Crockford เรียกมันผิดพลาด Kiro Risk คิดว่าเป็นเรื่องที่สมเหตุสมผล :

เหตุผลที่อยู่เบื้องหลังนี้คือnullในทางตรงกันข้ามกับundefinedคือ (และยังคงเป็น) มักจะใช้ที่วัตถุปรากฏ กล่าวอีกนัยหนึ่งnullมักใช้เพื่อแสดงการอ้างอิงที่ว่างเปล่าไปยังวัตถุ เมื่อ Brendan Eich สร้าง JavaScript ขึ้นมาเขาก็ทำตามกระบวนทัศน์เดียวกันและทำให้รู้สึกว่า "object" กลับคืนมา ในความเป็นจริงข้อมูลจำเพาะ ECMAScript กำหนดnullเป็นค่าดั้งเดิมที่แสดงถึงการขาดความตั้งใจของค่าวัตถุใด ๆ (ECMA-262, 11.4.11)


3
เนื่องจากฉันไม่สามารถหาวิดีโอได้ในตอนนี้ฉันจะโพสต์สิ่งนี้เพื่อคนที่อยากรู้อยากเห็นและไม่มีการอ้างอิงใด ๆ : Crockford อธิบายว่าค่าศูนย์ในการแก้ไขประเภทของโมฆะชี้ไปที่องค์ประกอบศูนย์ดัชนีในอาร์เรย์ประเภทได้อย่างไร การพัฒนาข้อผิดพลาดที่พวกไมโครซอฟท์เผยแพร่โดยไม่ตั้งใจเมื่อทำการคอมไพล์และรวบรวมใหม่ JS สำหรับเบราว์เซอร์
Áxel Costas Pena

6

จากหนังสือYDKJS

นี่เป็นข้อผิดพลาดที่ยาวนานใน JS แต่สิ่งที่น่าจะไม่ได้รับการแก้ไข รหัสที่มากเกินไปบนเว็บขึ้นอยู่กับข้อผิดพลาดและการแก้ไขมันจะทำให้เกิดข้อบกพร่องมากขึ้น!


1
อย่าไว้ใจทุกสิ่งที่เขียนในหนังสือ ฉันรักหนังสือเล่มนั้นจริง ๆ แต่ฉันไม่สามารถพิจารณาข้อผิดพลาดนั้นได้เนื่องจากข้อกำหนดของ ECMA สำหรับ JavaScript ระบุว่าประเภทของ null จะต้องเป็นวัตถุ
andreasonny83

4

ถ้าnullเป็นค่าดั้งเดิมทำไมต้องtypeof(null)ส่งคืน " object"

กล่าวโดยย่อ: เป็นข้อบกพร่องใน ECMAScript และควรเป็นประเภท null

การอ้างอิง: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null


1
ไม่มีที่ใดในเอกสารอ้างอิงของคุณระบุว่าเป็นข้อบกพร่อง
2867288

1
และไม่มีที่ไหนในสเป็คที่บอกว่า typeof ควรส่งคืนสิ่งใดนอกจาก "undefined", "object", "boolean", "number", "string", "function" และ "symbol" (ECMAScript 2015)
Brad Kent

1

ใน JavaScript ที่ว่างเปล่าคือ "ไม่มีอะไร" มันควรจะเป็นสิ่งที่ไม่มีอยู่จริง น่าเสียดายที่ JavaScript มีชนิดข้อมูลเป็นวัตถุ คุณสามารถพิจารณาข้อผิดพลาดใน JavaScript ที่พิมพ์ null เป็นวัตถุ มันควรจะเป็นโมฆะ


0

ใน JavaScript ประเภทของ null เป็น 'วัตถุ' ซึ่งไม่ถูกต้องแสดงว่า null เป็นวัตถุ นี่เป็นข้อผิดพลาดและสิ่งที่น่าเสียดายที่ไม่สามารถแก้ไขได้เนื่องจากจะทำให้รหัสที่มีอยู่เสียหาย


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.