หนึ่ง. สองต้นแบบ
หลายคนรู้ว่า JavaScript เป็นมรดกต้นแบบ ตัวสร้างแต่ละตัวมีสมาชิกต้นแบบซึ่งการสืบทอดของจาวาสคริปต์สามารถสวยงามได้
ในความเป็นจริงคุณลักษณะนี้เพียงอย่างเดียวไม่สามารถสืบทอดมรดกของ JavaScript ได้
ฉันจะไม่พูดอะไรมากเกี่ยวกับต้นแบบที่เราใช้ในรหัส คุณสามารถตรวจสอบข้อมูล
สมาชิกต้นแบบที่มองไม่เห็นอีกคนหนึ่ง
แต่ละอินสแตนซ์มีแอตทริบิวต์ต้นแบบที่ชี้ไปที่ต้นแบบ แอตทริบิวต์นี้ไม่สามารถเข้าถึงได้และไม่สามารถแก้ไขได้เนื่องจากนี่เป็นพื้นฐานสำหรับการรักษามรดก JavaScript
การคัดลอกรหัสมีดังนี้:
// คำสั่ง constructor
ฟังก์ชั่น guoyansi () {}
ฟังก์ชั่น guoyansiex () {}
// การสืบทอดต้นแบบ
guoyansiex.prototype = new guoyansi ();
// สร้างวัตถุ
var g1 = new guoyansiex ();
var g2 = new guoyansiex ();
วัตถุในรหัสด้านบนสามารถอธิบายได้ด้วยรูปต่อไปนี้
2. การบำรุงรักษาต้นแบบ
อินสแตนซ์ที่สร้างขึ้นโดยตัวสร้างที่มีแอตทริบิวต์ตัวสร้างชี้ไปที่ตัวสร้างเสมอ เราจะคิดว่าคำสั่งนั้นถูกต้องสำหรับเวลา
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น guoyansi () {}
var obj1 = new guoyansi ();
console.log (obj1.constructor === guoyansi); // true
ในความเป็นจริงตัวสร้างเองไม่มีแอตทริบิวต์ตัวสร้างดังนั้นแอตทริบิวต์นี้มาจากไหน?
คำตอบคือ: จากต้นแบบ
ดังนั้นข้อสรุปต่อไปนี้จะถูกดึง
การคัดลอกรหัสมีดังนี้: obj1.constructor === guoyansi.prototype.constructor === guoyansi
เนื่องจากเราสามารถค้นหาตัวสร้างผ่านตัวสร้างเราจึงสามารถปรับปรุงไดอะแกรมข้างต้นเพิ่มเติมได้
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น guoyansiex () {}
guoyansiex.prototype = new guoyansi ();
console.log (guoyansiex.constructor === guoyansiex) // false
ตามภาพด้านบนผลลัพธ์ข้างต้นควรเป็นจริง แต่ทำไมเท็จจึงเป็นเท็จ?
ตอนนี้ทำการวิเคราะห์
ต้นแบบของ Guoyansiex ถูกเขียนขึ้นใหม่โดยตัวอย่างของ Guoyansi ดังนั้นตัวสร้างในต้นแบบของ Guoyansiex จึงเป็นตัวอย่างของ Guoyansi
ตัวสร้างในอินสแตนซ์ Guoyansi มาจาก Guoyansi.prototype อย่างไรก็ตาม Guoyansi.prototype ยังไม่ได้รับการเขียนใหม่
ดังนั้นตัวสร้างของ Guoyansi.prototype ชี้ไปที่ Guoyansi (ตัวสร้าง);
จากการวิเคราะห์ข้างต้นเราได้สรุปข้อสรุปต่อไปนี้
การคัดลอกรหัสมีดังนี้: guoyansiex.constructor === guoyansi.constructor === Guoyansi;
หากข้อกำหนดคำสั่งของตัวสร้างมีความแม่นยำมากในระหว่างกระบวนการพัฒนาการประมวลผลต่อไปนี้สามารถทำได้
การคัดลอกรหัสมีดังนี้:
/** วิธี 1: **/
ฟังก์ชั่น guoyansi () {}
ฟังก์ชั่น guoyansiex () {}
guoyansiex.prototype = new guoyansi ();
guoyansiex.prototype.constructor = guoyansiex; // รีเซ็ตตัวชี้สร้างตัวสร้าง
การคัดลอกรหัสมีดังนี้:
-
วิธีที่ 2
-
ฟังก์ชั่น guoyansi () {}
ฟังก์ชั่น guoyansiex () {
this.constructor = arguments.callee;
-
guoyansiex.prototype = new guoyansi ();
การคัดลอกรหัสมีดังนี้:
-
วิธีที่ 3
-
ฟังก์ชั่น guoyansi () {}
ฟังก์ชั่น guoyansiex () {
this.constructor = guoyansiex;
-
guoyansiex.prototype = new guoyansi ();
3. การใช้ต้นแบบที่มองไม่เห็นคืออะไร?
เราสามารถใช้งานห่วงโซ่ต้นแบบที่มองเห็นได้เพื่อให้การสืบทอดของเราเสร็จสมบูรณ์ดังนั้นเราจึงไม่สามารถมองเห็นและใช้งานห่วงโซ่ต้นแบบที่มองไม่เห็นนี้ การใช้งานของมันคืออะไร?
มีคุณสมบัติในการสืบทอดเชิงวัตถุ: ความคล้ายคลึงกัน คลาสย่อยมีความคล้ายคลึงกับคลาสหลัก ดังนั้นในคลาสย่อยคุณไม่สามารถใช้ลบเพื่อลบสมาชิกที่สืบทอดมาจากคลาสแม่ กล่าวคือคลาสย่อยจะต้องมีลักษณะของชั้นเรียนหลัก
เพื่อรักษาคุณสมบัตินี้ JavaScript จะสร้างคุณสมบัติต้นแบบที่มองไม่เห็นภายในวัตถุและไม่อนุญาตให้ผู้ใช้เข้าถึงได้ ด้วยวิธีนี้ผู้ใช้สามารถปรับเปลี่ยนตัวสร้างเพื่อวัตถุประสงค์ใด ๆ
มันจะไม่ทำลายลักษณะของชั้นเด็กที่มีชั้นเรียนหลัก
กล่าวโดยย่อ: ต้นแบบภายในเป็นสิ่งจำเป็นโดยกลไกการสืบทอดต้นแบบของ JavaScript ในขณะที่ผู้ใช้ต้องใช้ต้นแบบภายนอกเพื่อใช้การสืบทอด
4. __proto__ ในเครื่องยนต์ Firefox Spidermonkey
ยังคงรหัสนี้
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น guoyansi () {}
guoyansi.prototype.age = 24;
ฟังก์ชั่น guoyansiex () {}
var obj1 = new guoyansi ();
guoyansiex.prototype = obj1;
guoyansiex.prototype.constructor = guoyansiex; // รีเซ็ตตัวชี้สร้างตัวสร้าง
var obj2 = new guoyansiex ();
ตอนนี้ฉันต้องการเข้าถึงอายุของคุณสมบัติของต้นแบบของ Guoyansi ระดับผู้ปกครองเริ่มต้นจาก OBJ
นี่คือความคิด
ขั้นตอนที่ 1: obj2 ====> obj2.constructor.prototype
ส่วนที่ 2: obj2.constructor.prototype ===> guoyansiex.prototype;
ส่วนที่ 3: guoyansiex.prototype ===> obj1;
ส่วนที่ 4: obj1.constructor ====> guoyansi
ส่วนที่ 5: guoyansi.prototype.age
เขียนแบบนี้: console.log (obj2.constructor.prototype.constructor.prototype.age) // 24;
ผลลัพธ์สุดท้ายคือ 24
ผลลัพธ์สุดท้ายคือ 24 สามารถดำเนินการได้ตามปกติ แต่ในหนังสือหลายเล่มมันบอกว่าหลังจากตัวสร้างได้รับการแก้ไขแล้วระดับไม่สามารถหาต้นแบบในชั้นเรียนหลักได้ ฉันไม่รู้ว่าเกิดอะไรขึ้น
เพียงพอของแอตทริบิวต์ที่กระชับมากขึ้นใน firefox._proto_
โดยค่าเริ่มต้น SpiderMonkey จะเพิ่มแอตทริบิวต์ที่เรียกว่า _proto_ ไปยังวัตถุที่สร้างขึ้นใด ๆ ซึ่งชี้ไปที่ต้นแบบที่ใช้โดยตัวสร้าง
ในความเป็นจริงมันเป็นห่วงโซ่ต้นแบบที่มองไม่เห็นที่เรากล่าวถึงข้างต้น แต่มันเป็นเพียงการเปิดเผยที่ปลอมตัวในสถานที่นี้
คุณสามารถเข้าถึงอายุด้วยวิธีนี้
console.log (obj2 .__ proto __.__ proto __. อายุ); // 24
สิ่งนี้ประสบความสำเร็จในการเข้าถึงแอตทริบิวต์ต้นแบบของคลาสแม่ แต่แอตทริบิวต์นี้ใช้ได้กับ Firefox เท่านั้นและจะมีข้อผิดพลาดในเบราว์เซอร์อื่น ๆ
ใน E5 วัตถุจะถูกขยายไปยัง Object.getPrototypeof () และคุณสามารถเข้าถึงต้นแบบคลาสแม่ทั้งหมดได้
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น guoyansi () {}
guoyansi.prototype.age = 24;
ฟังก์ชั่น guoyansiex () {}
var obj1 = new guoyansi ();
guoyansiex.prototype = obj1;
guoyansiex.prototype.constructor = guoyansiex; // รีเซ็ตตัวชี้สร้างตัวสร้าง
var obj2 = new guoyansiex ();
var proto = object.getPrototypeof (OBJ2);
ในขณะที่ (โปรโต) {
console.log (proto.constructor);
proto = object.getPrototypeof (proto);
-
console.log ("ต้นแบบของวัตถุ"+proto);
ผลที่ได้คือ: Guoyansiex
Guoyansi
วัตถุ
ต้นแบบ null สำหรับวัตถุ
โดยส่วนตัวแล้วฉันคิดว่าสิ่งเหล่านี้ควรได้รับการพิจารณาเป็นหนึ่งในสาระสำคัญของ JavaScript เชิงวัตถุ โปรดดูด้วยตัวคุณเองและใช้ในโครงการของคุณเองตามความต้องการของคุณ