ข้อเท็จจริง JS __proto__ “สนุก”
หากคุณติดตามฉันมานานพอ คุณรู้อยู่แล้วว่าฉันต่อต้าน__proto__
ฉันมากแค่ไหน และเนื่องจากมันได้มาตรฐาน ECMAScriptเมื่อนานมาแล้ว ก็ยังมีบางโอกาสที่ฉันพบว่าอย่างน้อยการใช้มันเพื่อสร้างแบรนด์ให้กับวัตถุที่ยอมรับได้ :
const factory = (fields, {prototype} = Object) => ({
__proto__: prototype,
...fields
});
// mimic an <a /> reference
factory({href: '/'}, HTMLAnchorElement);
นอกเหนือจากประสิทธิภาพแล้ว และโปรดทราบว่าฉันไม่ได้แนะนำการใช้งาน แบบทั่วไป __proto__
เลย โพสต์นี้มีอยู่ด้วยเหตุผลอื่น
Object.prototype.__proto__
ฉันค่อนข้างแน่ใจว่าทุกคนรู้ว่า __proto__ accessor ทำอะไรดังนั้นฉันอยากจะเสนอความท้าทายให้คุณ … และใช่ ทั้งหมดนี้เป็น JS ที่ถูกต้อง:
class Test {}
const __proto__ = Test.prototype;
// what do these operations return?
({__proto__} instanceof Test);
({__proto__: __proto__} instanceof Test);
({"__proto__": __proto__} instanceof Test);
({["__proto__"]: __proto__} instanceof Test);
// what do these operations return?
({__proto__}.__proto__ === Test.prototype);
({__proto__: __proto__}.__proto__ === Test.prototype);
({"__proto__": __proto__}.__proto__ === Test.prototype);
({["__proto__"]: __proto__}.__proto__ === Test.prototype);
หากคุณยังไม่ได้เรียกใช้ตัวอย่างข้อมูลเหล่านี้ด้วยตัวเองเพื่อทราบคำตอบ เราช่วยคุณได้! ในความท้าทายแรก ผลลัพธ์จะเป็นfalse
, true
, true
และfalse
อีกครั้ง และเหตุผลก็คือทั้งคู่{__proto__}
และ{["__proto__"]}
ถูกกำหนดให้เป็นคุณสมบัติของตัวเองในขณะที่การกำหนดผ่านไวยากรณ์ โดยไม่ได้ใช้คุณสมบัติไวยากรณ์พิเศษ แม้ว่าจะใส่เครื่องหมายอัญประกาศอยู่ก็ตาม จริง ๆ แล้วผ่านตัวObject.prototype.__proto__
เข้าถึง
ในทางกลับกัน ในความท้าทายที่สอง (ทั้งหมดtrue
) มันไม่สำคัญว่าเราจะเข้าถึง__proto__
โดยตรงหรือเป็น["__proto__"]
ดังนั้นโดยพื้นฐานแล้วจะไม่มีสมมาตรเป็นศูนย์ในวิธีที่เราสามารถเรียกใช้__proto__
setter จากวิธีที่เราสามารถเรียกใช้__proto__
getter เพียงครั้งเดียว เป็นทรัพย์สินของตัวเองหรือประตูมรดกเวทมนตร์
… และไม่ใช่แค่ __proto__
__xxx__
ฉันไม่ได้ตรวจสอบตัวเอง แต่ฉันเชื่อว่า accessor พิเศษแบบดั้งเดิมทุกตัว ต้องทนทุกข์ทรมานกับ __proto__
คำสาปเดียวกัน ดังนั้นโปรดใช้ความระมัดระวังในการผสมไวยากรณ์ JS สุดเจ๋งล่าสุดเพื่อกำหนดคุณสมบัติด้วยความตั้งใจและความคาดหวังที่แท้จริงของคุณ เนื่องจากสิ่งต่าง ๆ อาจกลายเป็นเรื่องกล้วย ๆ หากคุณพยายาม ฉลาดในการกำหนดคุณสมบัติเหล่านี้
และนั่นคือทั้งหมด!
ข้อสรุปเดียวจากโพสต์นี้น่าจะสรุปได้ดังนี้:
- อย่าใช้ส่วนที่ล้าสมัยแต่ยังใช้งานได้ของภาษา หากคุณต้องการหลีกเลี่ยงความประหลาดใจในวันนี้หรือพรุ่งนี้ เกี่ยวกับลักษณะการทำงานของสิ่งเหล่านี้ด้วยไวยากรณ์ใหม่
- ชอบความชัดเจน (และน่าเสียดายที่ช้ากว่า)
Object.setPrototypeOf
เมื่อใดก็ตามที่จำเป็นต้องมีการตั้งค่าต้นแบบของวัตถุด้วยตนเองอย่างเคร่งครัด แต่ให้ใช้คลาสในทุก ๆ กรณีทุกครั้งที่เป็นไปได้ - ลบโพสต์นี้ออกจากความทรงจำของคุณหรือย่อให้เป็นประโยคสั้นๆ เช่น “ ฉันไม่ควรใช้
__proto__
ในโค้ดของฉัน ” และเรียนรู้สิ่งใหม่ๆ แฟนซีที่ไม่ทำให้สมองหรือความรู้สึกของคุณยุ่งเหยิง