ในภาษาการเขียนโปรแกรมส่วนใหญ่มีคลาสและวัตถุและหนึ่งคลาสสามารถสืบทอดคลาสอื่น ๆ ได้
ใน JavaScript การสืบทอดเป็นแบบต้นแบบซึ่งหมายความว่าไม่มีคลาสใน JavaScript และแทนที่จะเป็นวัตถุหนึ่งที่สืบทอดวัตถุอื่น -
1. มรดกโปรโต
ในจาวาสคริปต์เมื่อกระต่ายวัตถุสืบทอดสัตว์วัตถุอื่นหมายความว่าจะมีคุณสมบัติพิเศษในวัตถุกระต่าย: กระต่าย. __ proto__ = สัตว์;
เมื่อเข้าถึงวัตถุกระต่ายหากล่ามไม่สามารถหาคุณสมบัติในกระต่ายได้มันจะเป็นไปตามห่วงโซ่ __proto__ เพื่อค้นหาในวัตถุสัตว์
แอตทริบิวต์ __proto__ ในเกาลัดสามารถเข้าถึงได้ใน Chrome และ Firefox เท่านั้น โปรดดูเกาลัด:
var iment = {eats: true} var rabbit = {jumps: true} Rabbit .__ proto__ = iment // มรดก (rabbit.eats) // trueแอตทริบิวต์ Eats เข้าถึงได้จากวัตถุสัตว์
หากพบแอตทริบิวต์ในวัตถุกระต่ายคุณลักษณะของโปรโตจะไม่ถูกตรวจสอบ
มามีเกาลัดอีกอันกันเถอะ เมื่อมีแอตทริบิวต์ Eats ในคลาสย่อยคลาสแม่จะไม่สามารถเข้าถึงได้
var iment = {eats: true} var fedUprabbit = {eats: false} fedUprabbit .__ proto__ = การแจ้งเตือนสัตว์ (fedUprabbit.eats) // falseนอกจากนี้คุณยังสามารถเพิ่มฟังก์ชั่นในสัตว์และสามารถเข้าถึงได้ในกระต่าย
var iment = {eat: function () {alert ("ฉันเต็ม") this.full = true}} var rabbit = {jump: function () { / * บางสิ่งบางอย่าง * /}} Rabbit .__ Proto__ = สัตว์(1) rabbit.eat ():
ฟังก์ชั่น Rabbit.eat () ดำเนินการในสองขั้นตอนต่อไปนี้:
ก่อนอื่นล่ามจะมองหา Rabbit.eat ไม่มีฟังก์ชั่นการกินในกระต่ายดังนั้นมันจึงมองขึ้นไปตามกระต่าย. __ proto__ และพบมันในสัตว์
ฟังก์ชั่นทำงานด้วย Rabbit นี้ = ค่านี้ไม่มีส่วนเกี่ยวข้องกับแอตทริบิวต์ __proto__
ดังนั้นสิ่งนี้ full = true ในกระต่าย:
มาดูกันว่าการค้นพบใหม่ที่เราทำที่นี่ วัตถุเรียกฟังก์ชั่นหลัก แต่สิ่งนี้ยังชี้ไปที่วัตถุเองซึ่งเป็นมรดก
วัตถุที่อ้างอิงโดย __proto__ เรียกว่าต้นแบบและสัตว์เป็นต้นแบบของกระต่าย (หมายเหตุของนักแปล: นี่คือแอตทริบิวต์ __proto__ ของกระต่ายหมายถึงคุณลักษณะต้นแบบของสัตว์)
(2) ค้นหาเมื่ออ่านไม่ใช่เมื่อเขียน
เมื่ออ่านวัตถุเช่น this.prop ล่ามจะมองหาคุณสมบัติในต้นแบบ
เมื่อตั้งค่าแอตทริบิวต์เช่น this.prop = value ดังนั้นจึงไม่มีเหตุผลที่จะค้นหาและแอตทริบิวต์นี้ (Prop) จะถูกเพิ่มลงในวัตถุนี้โดยตรง (นี่คือสิ่งนี้) ลบ obj.prop คล้ายกันมันจะลบคุณสมบัติของวัตถุเท่านั้นและคุณสมบัติในต้นแบบยังคงไม่บุบสลาย
(3) เกี่ยวกับโปรโต
หากคุณกำลังอ่านคำแนะนำที่นี่เราเรียก __proto__ ซึ่งแสดงในคู่มือเป็น [[ต้นแบบ]] วงเล็บทั้งสองมีความสำคัญเนื่องจากมีคุณสมบัติอื่นที่เรียกว่าต้นแบบ
2. Object.create, Object.getPrototypeof
__proto__ เป็นสถานที่ให้บริการที่ไม่ได้มาตรฐานซึ่งจัดทำโดย Chrome/Firefox และยังคงมองไม่เห็นในเบราว์เซอร์อื่น ๆ
เบราว์เซอร์ที่ทันสมัยทั้งหมดยกเว้นโอเปร่า (เช่น> 9) สนับสนุนฟังก์ชั่นมาตรฐานสองฟังก์ชั่นเพื่อจัดการกับปัญหาต้นแบบ:
Object.ceate (prop [, อุปกรณ์ประกอบฉาก])
สร้างวัตถุเปล่าด้วยโปรโตที่กำหนด:
var iment = {eats: true} rabbit = object.create (Animal) Alert (rabbit.eats) // trueรหัสด้านบนสร้างวัตถุกระต่ายที่ว่างเปล่าและต้นแบบถูกตั้งค่าเป็นสัตว์
หลังจากสร้างวัตถุกระต่ายแล้วเราสามารถเพิ่มคุณสมบัติให้กับมันได้:
var iment = {กิน: true} rabbit = object.create (สัตว์) rabbit.jumps = trueพารามิเตอร์ที่สองของฟังก์ชัน Object.creat เป็นทางเลือกซึ่งอนุญาตให้ตั้งค่าคุณสมบัติเช่นวัตถุใหม่ สิ่งนี้ถูกละเว้นเนื่องจากมรดกของความสัมพันธ์ของเรา
(1) Object.getPrototypeof (OBJ)
ส่งคืนค่าของ obj .__ proto__ ฟังก์ชั่นนี้เป็นมาตรฐานและสามารถใช้ในเบราว์เซอร์ที่ไม่สามารถเข้าถึงแอตทริบิวต์ __proto__ โดยตรง
var iment = {eats: true} rabbit = object.create (สัตว์) การแจ้งเตือน (Object.getPrototypeof (กระต่าย) === สัตว์) // trueเบราว์เซอร์ที่ทันสมัยอนุญาตให้อ่านค่าแอตทริบิวต์ __Proto__ แต่ไม่สามารถตั้งค่าได้
3. ต้นแบบ
มีวิธีการข้ามเบราว์เซอร์ที่ดีในการตั้งค่าแอตทริบิวต์ __proto__ ซึ่งจะใช้ฟังก์ชั่นตัวสร้าง จดจำ! ฟังก์ชั่นใด ๆ สร้างวัตถุผ่านคำหลักใหม่
เกาลัด:
ฟังก์ชั่นกระต่าย (ชื่อ) {this.name = name} var rabbit = ใหม่ Rabbit ('John') การแจ้งเตือน (rabbit.name) // Johnการดำเนินการใหม่ตั้งค่าคุณสมบัติของต้นแบบเป็นคุณสมบัติ __proto__ ของวัตถุกระต่าย
ลองมาดูหลักการของมันตัวอย่างเช่นวัตถุกระต่ายใหม่ที่สืบทอดสัตว์
var iment = {eats: true} function Rabbit (ชื่อ) {this.name = name} Rabbit.prototype = AnimalVar Rabbit = Rabbit ใหม่ ('John') Alert (Rabbit.eats) // True เพราะ Rabbit.Rabbit.prototype = หมายถึงตัวอักษรสัตว์: ตั้ง __proto__ = สัตว์สำหรับวัตถุทั้งหมดที่สร้างโดย New Rabbit
4. Object-Cross-Browser Create (Proto)
ฟังก์ชั่น Object.create (Prop) มีประสิทธิภาพเนื่องจากอนุญาตให้รับการสืบทอดโดยตรงจากวัตถุที่กำหนด สามารถจำลองได้ด้วยรหัสต่อไปนี้:
ฟังก์ชันสืบทอด (proto) {function f () {} f.prototype = proto return f} ใหม่มรดก (สัตว์) นั้นเทียบเท่ากับ object.create (สัตว์) ส่งคืนวัตถุเปล่าและวัตถุ. __ proto__ = สัตว์
เกาลัด:
var iment = {eats: true} var rabbit = สืบทอด (สัตว์) Alert (rabbit.eats) // Truealert (rabbit.hasownproperty ('eats')) // false จากต้นแบบมาดูกันว่าหลักการของมันคืออะไร:
ฟังก์ชันสืบทอด (proto) {function f () {} // (1) f.prototype = proto // (2) ส่งคืน f () ใหม่ f () // (3)}(1) ฟังก์ชั่นใหม่ถูกสร้างขึ้นและฟังก์ชั่นไม่ได้ตั้งค่าแอตทริบิวต์ใด ๆ ให้กับสิ่งนี้ดังนั้น `f` ใหม่จะสร้างวัตถุที่ว่างเปล่า
(2) `f.prototype` ถูกตั้งค่าเป็น proto
(3) `new` f สร้างวัตถุที่ว่างเปล่าวัตถุ` __proto__ = f.prototype` ของวัตถุ
(4) บิงโก! เราได้รับวัตถุที่ว่างเปล่าที่สืบทอด `proto '
ฟังก์ชั่นนี้ใช้กันอย่างแพร่หลายในห้องสมุดและเฟรมเวิร์กต่างๆ
ฟังก์ชั่นของคุณยอมรับวัตถุที่มีตัวเลือก
/ * ตัวเลือกประกอบด้วยการตั้งค่าเมนู: ความกว้างความสูง ฯลฯ */เมนูฟังก์ชั่น (ตัวเลือก) {// ... } คุณต้องการตั้งค่าเมนูฟังก์ชันตัวเลือกบางตัว (ตัวเลือก) {optopps.width = opotions.width || 300 // ตั้งค่าเริ่มต้น // ... }- - - แต่การเปลี่ยนค่าพารามิเตอร์อาจให้ผลลัพธ์ที่ไม่ถูกต้องเนื่องจากตัวเลือกอาจใช้ในรหัสภายนอก ทางออกคือการโคลนวัตถุตัวเลือกคัดลอกแอตทริบิวต์ทั้งหมดลงในวัตถุใหม่และแก้ไขในวัตถุใหม่
วิธีแก้ปัญหานี้ด้วยการสืบทอด? ตัวเลือก PS สามารถเพิ่มการตั้งค่า แต่ไม่สามารถลบได้
สารละลาย
คุณสามารถสืบทอดตัวเลือกและแก้ไขหรือเพิ่มคุณสมบัติใหม่ในคลาสย่อย
ฟังก์ชั่นสืบทอด (proto) {function f () {} f.prototype = proto return ใหม่เมนู F} ใหม่ (ตัวเลือก) {var opts = สืบทอด (ตัวเลือก) opts.width = opts.width || 300 // ... }การดำเนินการทั้งหมดใช้ได้เฉพาะในวัตถุย่อย เมื่อวิธีการเมนูสิ้นสุดรหัสภายนอกยังสามารถใช้วัตถุตัวเลือกที่ไม่ได้แก้ไข การลบการดำเนินการมีความสำคัญมากที่นี่ หากความกว้างเป็นคุณสมบัติในต้นแบบให้ลบ opts.width จะไม่มีผลกระทบใด ๆ
5. HasownProperty
วัตถุทั้งหมดมีฟังก์ชั่น HasownProperty ซึ่งสามารถใช้ในการตรวจสอบว่าคุณสมบัติเป็นของตัวเองหรือต้นแบบ
เกาลัด:
ฟังก์ชั่นกระต่าย (ชื่อ) {this.name = name} rabbit.prototype = {eats: true} var rabbit = กระต่ายใหม่ ('John') แจ้งเตือน (rabbit.hasownproperty ('eats')) // false6. วนรอบด้วย/ไม่มีคุณสมบัติที่สืบทอดมา
สำหรับ .. ในลูปเอาต์พุตคุณสมบัติทั้งหมดของวัตถุรวมถึงตัวของมันเองและต้นแบบ
ฟังก์ชั่นกระต่าย (ชื่อ) {this.name = name} rabbit.prototype = {eats: true} var rabbit = กระต่ายใหม่ ('John') สำหรับ (var p ในกระต่าย) {แจ้งเตือน (p + "=" + rabbit [p]) // ส่งออกทั้ง "ชื่อ"ใช้ HasownProperty เพื่อกรองคุณสมบัติของวัตถุ:
ฟังก์ชั่นกระต่าย (ชื่อ) {this.name = name} rabbit.prototype = {eats: true} var rabbit = กระต่ายใหม่ ('john') สำหรับ (var p ในกระต่าย) {ถ้า (! rabbit.hasownproperty (p))7. สรุป
JavaScript ใช้การสืบทอดผ่านโปรโตแอตทริบิวต์พิเศษ
เมื่อเข้าถึงคุณสมบัติของวัตถุหากล่ามไม่สามารถหาได้ในวัตถุมันจะยังคงค้นหาคุณสมบัติฟังก์ชันต่อไปชี้ไปที่วัตถุไม่ใช่ต้นแบบ
กำหนด obj.prop = ค่า, ลบ obj.prop
จัดการโปรโต:
Chrome และ Firefox สามารถเข้าถึงแอตทริบิวต์ __proto__ ของวัตถุได้โดยตรง เบราว์เซอร์ที่ทันสมัยส่วนใหญ่รองรับการเข้าถึงแบบอ่านอย่างเดียวโดยใช้ Object.getPrototypeof (OBJ)
Object.create (proto) สามารถสร้างวัตถุเด็กที่ว่างเปล่าด้วยโปรโตที่กำหนดหรือบรรลุฟังก์ชั่นเดียวกันผ่านรหัสต่อไปนี้:
ฟังก์ชันสืบทอด (proto) {function f () {} f.prototype = proto return ใหม่ f ()}วิธีอื่น ๆ :
สำหรับ .. ในลูปเอาต์พุตคุณสมบัติทั้งหมดของวัตถุ (รวมถึงตัวของมันเองและต้นแบบ) และห่วงโซ่ต้นแบบของวัตถุ
หากอานอสังหาริมทรัพย์เป็นของวัตถุ OBJ แล้ว obj.hasownproperty (prop) จะส่งคืนจริงมิฉะนั้นเท็จ