การสืบทอดใน js สามารถแบ่งออกเป็นสองประเภท: การเลียนแบบวัตถุและการเชื่อมโยงต้นแบบ
1. การเลียนแบบวัตถุมีสามประเภท : วิธีการแอตทริบิวต์ชั่วคราว, วิธีการเรียก () และวิธีใช้ ()
1. วิธีแอตทริบิวต์ชั่วคราว
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่นบุคคล (ชื่อ) {
this.name = ชื่อ;
this.say = ฟังก์ชั่น () {
alert('ฉันชื่อ'+this.name);
-
-
ฟังก์ชั่น F2E (ชื่อ, ID) {
this.temp = บุคคล;
this.temp (ชื่อ);
ลบ this.temp;
this.id = ไอดี;
this.showId = ฟังก์ชั่น(){
alert('สวัสดีครับท่าน หมายเลขงานของผมคือ '+this.id);
-
-
var simon = F2E ใหม่ ('ไซมอน',9527);
ไซมอน.พูด();
simon.showId();
2.call()/apply() วิธีการ
โดยพื้นฐานแล้ว จะเปลี่ยนตัวชี้ของตัวชี้นี้
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่นบุคคล (ชื่อ) {
this.name = ชื่อ;
this.say = ฟังก์ชั่น () {
alert('ฉันชื่อ'+this.name);
-
-
ฟังก์ชั่น F2E (ชื่อ, ID) {
Person.call(this,name); //apply() วิธีการเปลี่ยนเป็น Person.apply(this,new Array(name));
this.id = ไอดี;
this.showId = ฟังก์ชั่น(){
alert('สวัสดีครับท่าน หมายเลขงานของผมคือ '+this.id);
-
-
var simon = F2E ใหม่ ('ไซมอน',9527);
ไซมอน.พูด();
simon.showId();
ข้อเสีย: มาดูแผนภาพการจัดสรรหน่วยความจำนี้กันก่อน:
ในแนวคิด OO หลังจากสร้างอินสแตนซ์ใหม่แล้ว วัตถุจะสร้างพื้นที่ของตัวเองในหน่วยความจำฮีป เป็นที่น่าสังเกตว่าส่วนของโค้ดนี้ วิธีการสมาชิกมีอยู่ในส่วนของรหัสนี้ และวิธีการที่ใช้ร่วมกัน ปัญหาอยู่ตรงนี้ เมื่อสืบทอดผ่านการเลียนแบบ Object เมธอดทั้งหมดจะชี้ไปที่สิ่งนี้ กล่าวคือ หลังจากสร้างใหม่ แต่ละอินสแตนซ์จะมีเมธอดเมมเบอร์นี้ซึ่งไม่ได้แชร์ ซึ่งส่งผลให้หน่วยความจำจำนวนมากสูญเปล่า และผ่านการเลียนแบบวัตถุ ตัวแปรและวิธีการที่กำหนดผ่านต้นแบบไม่สามารถสืบทอดได้ ตัวอย่างเช่น รหัสต่อไปนี้จะทำให้เกิดข้อผิดพลาด:
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่นบุคคล (ชื่อ) {
this.name = ชื่อ;
this.say = ฟังก์ชั่น () {
alert('ฉันชื่อ'+this.name);
-
-
บุคคล.ต้นแบบ.อายุ = 20;
Person.prototype.sayAge = function(){alert('อายุของฉันคือ '+this.age)};
ฟังก์ชั่น F2E (ชื่อ, ID) {
Person.apply(นี่,อาร์เรย์ใหม่(ชื่อ));
this.id = ไอดี;
this.showId = ฟังก์ชั่น(){
alert('สวัสดีครับท่าน หมายเลขงานของผมคือ '+this.id);
-
-
var simon = F2E ใหม่ ('ไซมอน',9527);
simon.sayAge(); //Prompt TypeError: simon.sayAge ไม่ใช่ฟังก์ชัน
2. วิธีลูกโซ่ต้นแบบ
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่นบุคคล () {
this.name = 'ไซมอน';
-
Person.prototype.say = ฟังก์ชั่น(){
alert('ฉันชื่อ'+this.name);
-
ฟังก์ชั่น F2E(id){
this.id = ไอดี;
this.showId = ฟังก์ชั่น(){
alert('สวัสดีครับท่าน หมายเลขงานของผมคือ '+this.id);
-
-
F2E.prototype = บุคคลใหม่ ();
var simon = F2E ใหม่ (9527);
ไซมอน.พูด();
simon.showId();
alert(simon.hasOwnProperty('id')); //ตรวจสอบว่าเป็นทรัพย์สินของตัวเองหรือไม่
จากนั้น ทำตามตัวอย่างด้านบนเพื่อทำความเข้าใจแนวคิดลูกโซ่ต้นแบบ js ต่อไปนี้:
สายโซ่ต้นแบบสามารถเข้าใจได้ว่า: แต่ละอ็อบเจ็กต์ใน js มีแอตทริบิวต์ __proto__ ที่ซ่อนอยู่ แอตทริบิวต์ __proto__ ของอ็อบเจ็กต์อินสแตนซ์ชี้ไปที่วิธีต้นแบบของคลาสนั้น และวิธีการต้นแบบนี้สามารถกำหนดให้กับออบเจ็กต์อินสแตนซ์อื่นได้ วัตถุนี้จำเป็นต้องชี้ไปที่คลาสของมัน จึงสร้างห่วงโซ่ซึ่งก็คือ
คัดลอกรหัสรหัสดังต่อไปนี้:
F2E.prototype = บุคคลใหม่()
ประโยคนี้คือกุญแจสำคัญ เมื่อวัตถุ js อ่านแอตทริบิวต์บางอย่าง มันจะค้นหาแอตทริบิวต์ของตัวเองก่อน หากไม่มีแอตทริบิวต์ มันจะค้นหาแอตทริบิวต์ของวัตถุบนห่วงโซ่ต้นแบบ กล่าวอีกนัยหนึ่ง สามารถใช้วิธีการร่วมกันของห่วงโซ่ต้นแบบได้ ซึ่งช่วยแก้ปัญหาการเลียนแบบวัตถุและการสูญเสียหน่วยความจำ
ตอนนี้เรามาพูดถึงข้อเสีย:
ข้อเสียที่เห็นได้ชัดเจน การสืบทอดลูกโซ่ต้นแบบหมายความว่าไม่สามารถส่งพารามิเตอร์ไปยังคลาสพาเรนต์ได้เมื่อสร้างอินสแตนซ์คลาสย่อย นี่คือสาเหตุที่ฟังก์ชัน Person() ในตัวอย่างนี้ไม่มีพารามิเตอร์และเขียนโดยตรงเป็น this.name="Simon" รหัสต่อไปนี้จะไม่บรรลุผลตามที่ต้องการ:
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่นบุคคล (ชื่อ) {
this.name = ชื่อ;
-
Person.prototype.say = ฟังก์ชั่น(){
alert('ฉันชื่อ'+this.name);
-
ฟังก์ชั่น F2E (ชื่อ, ID) {
this.id = ไอดี;
this.showId = ฟังก์ชั่น(){
alert('สวัสดีครับท่าน หมายเลขงานของผมคือ '+this.id);
-
-
F2E.prototype = บุคคลใหม่ ();
var simon = F2E ใหม่ ("ไซมอน",9527);
ไซมอน.พูด();
simon.showId();
ฟังก์ชั่นบุคคล (ชื่อ) {
this.name = ชื่อ;
-
Person.prototype.say = ฟังก์ชั่น(){
alert('ฉันชื่อ'+this.name);
-
ฟังก์ชั่น F2E (ชื่อ, ID) {
this.id = ไอดี;
this.showId = ฟังก์ชั่น(){
alert('สวัสดีครับท่าน หมายเลขงานของผมคือ '+this.id);
-
-
F2E.prototype = new Person(); //Value ไม่สามารถส่งผ่านได้ที่นี่ ทั้ง this.name และ name จะไม่ทำงาน เป็นไปได้ที่จะเขียน F2E.prototype = new Person('wood') โดยตรง แต่ในกรณีนี้คือ simon พูด( ) กลายเป็น ฉันชื่อไม้
var simon = F2E ใหม่ ("ไซมอน",9527);
simon.say(); //ป๊อปอัพ ชื่อของฉันไม่ได้กำหนดไว้
simon.showId();
สุดท้ายนี้ ให้ฉันสรุปสิ่งที่ฉันคิดว่าเป็นวิธีที่ดีกว่าในการใช้ตัวแปรสมาชิกโดยใช้การเลียนแบบวัตถุ และวิธีการสมาชิกใช้การเชื่อมโยงต้นแบบ รหัสมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่นบุคคล (ชื่อ) {
this.name = ชื่อ;
-
Person.prototype.say = ฟังก์ชั่น(){
alert('ฉันชื่อ'+this.name);
-
ฟังก์ชั่น F2E (ชื่อ, ID) {
Person.call(นี่,ชื่อ);
this.id = ไอดี;
-
F2E.prototype = บุคคลใหม่ ();
//หมายเหตุรายละเอียดหนึ่งที่นี่ showId ไม่สามารถเขียนหน้า F2E.prototype = new Person();
F2E.prototype.showId = ฟังก์ชั่น(){
alert('สวัสดีครับท่าน หมายเลขงานของผมคือ '+this.id);
-
var simon = F2E ใหม่ ("ไซมอน",9527);
ไซมอน.พูด();
simon.showId();