JavaScript ใช้การสืบทอดต้นแบบตามค่าเริ่มต้น แม้ว่าจะไม่มีแนวคิดเกี่ยวกับคลาส แต่ฟังก์ชันของคลาสก็สามารถทำหน้าที่เป็นตัวสร้างได้ ตัวสร้างที่รวมกับสิ่งนี้และตัวใหม่สามารถสร้างคลาสที่คล้ายกับ Java ได้ ดังนั้น JavaScript จึงสามารถจำลองการสืบทอดตามคลาสโดยการขยายตัวเอง
JavaScript เช่นเดียวกับภาษาเชิงวัตถุอื่นๆ ใช้การอ้างอิงสำหรับประเภทวัตถุ ตัวแปรที่เก็บวัตถุเป็นเพียงที่อยู่ ในขณะที่ข้อมูลประเภทพื้นฐานคือค่า เมื่อจัดเก็บวัตถุบนต้นแบบ อาจมีข้อผิดพลาดอยู่บ้าง
มาดูตัวอย่างแรกกันก่อน
คัดลอกรหัสรหัสดังต่อไปนี้:
var create = function() {
ฟังก์ชั่น Fn() {}
ฟังก์ชั่นส่งคืน (พาเรนต์) {
Fn.prototype = ผู้ปกครอง
คืน Fn ใหม่
-
-
var parent = {
ชื่อ'แจ๊ค'
อายุ: 30,
isMarried: เท็จ
-
var child = สร้าง (พาเรนต์)
console.log (ลูก)
ฟังก์ชันเครื่องมือสร้างจะใช้การสืบทอดต้นแบบพื้นฐาน ทุกครั้งที่เรียกใช้การสร้าง ออบเจ็กต์ใหม่จะถูกคัดลอกตามคุณสมบัติหลักของออบเจ็กต์ใหม่ ในที่นี้พาเรนต์มีแอตทริบิวต์สามรายการ ซึ่งทั้งหมดเป็นประเภทข้อมูลพื้นฐาน ได้แก่ สตริง ตัวเลข และบูลีน
ตอนนี้ให้แก้ไขลูกเพื่อดูว่าจะส่งผลกระทบต่อผู้ปกครองหรือไม่
คัดลอกรหัสรหัสดังต่อไปนี้:
child.name = 'ลิลลี่'
เด็กอายุ = 20,
child.isMarried = จริง
console.log (ลูก)
console.log (พาเรนต์)
ผลลัพธ์มีดังนี้
นั่นคือการปรับเปลี่ยนลูกจะไม่ส่งผลกระทบต่อผู้ปกครอง
ลองดูอีกตัวอย่างหนึ่ง
คัดลอกรหัสรหัสดังต่อไปนี้:
var create = function() {
ฟังก์ชั่น Fn() {}
ฟังก์ชั่นส่งคืน (พาเรนต์) {
Fn.prototype = ผู้ปกครอง
คืน Fn ใหม่
-
-
var parent = {
ข้อมูล: {
ชื่อ'แจ๊ค'
อายุ: 30,
isMarried: เท็จ
-
ภาษา: ['ชวา']
-
var child = สร้าง (พาเรนต์)
child.data.name = 'ลิลลี่'
เด็ก.data.age = 20
child.data.isMarried = จริง
child. language.push ('จาวาสคริปต์')
console.dir (ลูก)
console.dir (พาเรนต์)
โปรดทราบว่าแอตทริบิวต์ทั้งสองของ parent ที่นี่ ข้อมูล และ ภาษา เป็นทั้งประเภทการอ้างอิง ประเภทหนึ่งคือวัตถุ และอีกประเภทหนึ่งคืออาร์เรย์ ลูกยังคงสืบทอดมาจากผู้ปกครอง จากนั้นลูกจะถูกแก้ไข ผลลัพธ์มีดังนี้
อย่างที่คุณเห็น ขณะนี้ผู้ปกครองได้รับการแก้ไขแล้ว และชื่อ อายุ ฯลฯ ของเด็กก็เหมือนกัน นี่คือสิ่งที่ต้องระวังเมื่อใช้การสืบทอดต้นแบบ
วิธีที่ดีกว่าในการใช้มรดกคือ:
1. คุณลักษณะข้อมูลใช้การสืบทอดคลาส (ค้างอยู่บนนี้) เพื่อให้สามารถกำหนดค่าผ่านพารามิเตอร์ได้เมื่อใหม่
2. วิธีการนี้ใช้การสืบทอดต้นแบบซึ่งสามารถบันทึกหน่วยความจำได้ ในเวลาเดียวกัน การแทนที่วิธีการด้วยคลาสย่อยจะไม่ส่งผลกระทบต่อคลาสพาเรนต์
ต่อไปนี้เป็นฟังก์ชันเครื่องมือการเขียนที่ตรงตามสองจุดข้างต้น
คัดลอกรหัสรหัสดังต่อไปนี้:
-
* @param {สตริง} ชื่อคลาส
* @param {สตริง/ฟังก์ชัน} superCls
* โรงงาน @param {Function}
-
ฟังก์ชั่น $class (ชื่อ, superClass, โรงงาน) {
ถ้า (superClass === '') superClass = Object
functionclazz() {
ถ้า (ประเภทของ this.init === 'ฟังก์ชั่น') {
this.init.apply (สิ่งนี้ ข้อโต้แย้ง)
-
-
var p = clazz.prototype = superCls ใหม่
clazz.prototype.constructor = แคลซ
clazz.prototype.className = ชื่อคลาส
var supr = superCls.ต้นแบบ
window[className] = clazz
โรงงานโทร (p, supr)
-
เมื่อวางประเภทอ็อบเจ็กต์บนต้นแบบของคลาสพาเรนต์ โปรดใช้ความระมัดระวังเมื่อคลาสย่อยแก้ไข ในกรณีนี้ อินสแตนซ์ทั้งหมดของคลาสย่อยที่สืบทอดมาจากคลาสพาเรนต์จะถูกแก้ไข และจุดบกพร่องที่เกิดจากสิ่งนี้หาได้ยากมาก
มีการเพิ่ม API ใหม่ลงใน ES5 เพื่อใช้การสืบทอดต้นแบบ: Object.create คุณสามารถใช้มันเพื่อแทนที่ฟังก์ชันสร้างที่นำไปใช้เองด้านบนได้ดังนี้
คัดลอกรหัสรหัสดังต่อไปนี้:
var parent = {
ชื่อ'แจ๊ค'
อายุ: 30,
isMarried: เท็จ
-
var child = Object.create (พาเรนต์)
console.log (ลูก)