קורס Front-End Web Development שיעור שיתוף קוד באמצעות ״ירושה״


זה נושא דיון מלווה לערך המקורי ב- https://www.tocode.co.il/bundles/html5-web-development/lessons/prototype-chain

היי ניסיתי לפי השיעור הזה לבנות שני מחלקות שמדגימות את אותu עניין של שרשרת פרוטוטייפ
בניתי שני מחלקות שנקראת ANIMAL וDOG
להלן הקוד :

function Animal (name){
    this.name=name;
    this.age=0;
}

Animal.prototype.growUp= function (){
    this.age++;
};

Animal.prototype.eat = function (){
    console.log('i am eatting now...');
}

function Dog(){
    Animal.call(this);
    this.food = 'naknikik';

}

Dog.prototype = Object.create(Animal.prototype);

Dog.prototype.bark = function (){
    console.log('i am barking now...' );
};


var dog1 = new Dog('gili');

השאלה שלי מדוע ביצירת האובייקט DOG לא קיבל את המשתנה NAME שהועבר לו כפרמטר ?
במקום השם ‘gili’ בשדה name יש undefined

שים לב לפונקציה Dog:

function Dog(){
    Animal.call(this);
    this.food = 'naknikik';

}

ובפרט לשורה הראשונה בפונקציה:

Animal.call(this);

חסר שם העברת פרמטר name לפונקציה Animal.

אוקי היה לי קצת בילבלול בהבנה חשבתי שכאשר הקריאה :

Animal.call(this);

מתבצעת היא באופן אוטומטי מעביר את המידע השמור מאובייקט DOG
כי כל העניין הזה שיש שדה name לDOG וחשבתי שזה מעובר לבנאי האב גם אם לא ציינתי אותו כמפרמטר.
הקוד מחדש

function Animal (name){
    this.name=name;
    this.age=0;
}

Animal.prototype.growUp= function (){
    this.age++;
};

Animal.prototype.eat = function (){
    console.log('i am eatting now...');
}

function Dog(name){
    Animal.call(this,name);
    this.food = 'naknikik';

}

Dog.prototype = Object.create(Animal.prototype);

Dog.prototype.bark = function (){
    console.log('i am barking now...' );
};


var dog1 = new Dog('gili');

לייק 1

מעולה ואני מוסיף וחושב שיש המון ערך בלהבין איך הדברים האלה עובדים מתחת לפני השטח בגירסת ES5 במיוחד אחרי זה כשלומדים את התחביר של ES6 classes כי הרעיונות שם בנויים אחד לאחד על המנגנונים האלה.

לא הצלחתי להבין לגמרי את השיעור הזה - לא ברור מה מייצג כעת ה- this בכל פונקציה למשל ב- drive …
למען האמת לא הבנתי מה בדיוק עושה הפונקציה של object.create
לחידוד השאלה - איך זה שה- NEW של ה- car לא דורס את ההגדרה של האב טיפוס שהגדרנו למעלה ?

כדאי לחשוב על האב-טיפוס לא בצורה של ירושה משפות אחרות אלא בצורה של שרשראות.

  1. ל Vehicle יש Prototype שכולל את הפונקציה isFasterThan.
  2. ל Car יש Prototype שכולל את הפונקציה drive.
  3. ל Prototype של Car גם יש Prototype וזה בדיוק ה Prototype של Vehicle

או בציור נניח ש c הוא אוביקט מסוג Car אז כל פעם שמפעילים פונקציה מ c הדפדפן יחפש את הפונקציה בכל האוביקטים האלה לפי הסדר:

c -> Car.prototype -> Vehicle.prototype

זה אומר שכשנכתוב c.drive קודם כל הדפדפן יחפש באוביקט c אם יש פונקציה drive. אם יש היא תופעל. אם אין הדפדפן יחפש ב Car.prototype אם יש פונקציה בשם drive ואם יש היא תופעל וכך הלאה לאורך כל השרשרת.

הפונקציה Object.create יוצרת אוביקט חדש שה Prototype שלו הוא בדיוק מה שהעברנו כפרמטר. כלומר השורה:

Car.prototype = Object.create(Vehicle.prototype);

שומרת ב Car.prototype אוביקט חדש שה Prototype שלו הוא Vehicle.prototype וכך יוצרת את השרשרת.

עדיין לא ברור לגמרי

  1. כדי להגדיר את ה- prototype של Car שיהיה לו גם prototype של Vehicle - היה צריך לכתוב
Car.prototype.prototype  = Object.create(Vehicle.prototype);
  1. איך שזה רשום עכשיו - אנחנו מכניסים ל - Car.prototype את Vehicle.prototype , אבל אז ב- NEW (לפי מה שהוסבר בשיעור ) אנחנו מכניסים
(Car.prototype  = Object.create(Car.prototype);

הי ינון,

בתוך פונקציית הבנאי Car נרשמה השורה:

Vehicle.call(this);

ממה שהבנתי תפקידה “לקשור” את מחלקה Vehicle למחלקת המכונית Car.
מדוע לא מספיק לרשום:

Vehicle(this);

כלומר מה תפקיד המילה השמורה call?
האם זה בגלל שלא ניתן להפעיל ישירות את הפונקציה על האוביקט המועבר this?
תודה מראש.

הי,

הפרמטר this לא עובר בתור פרמטר רגיל (שים לב שהפונקציה Vehicle לא מצפה לקבל פרמטרים). הדרך ב JavaScript להעביר לפונקציה ערך עבור הפרמטר this היא באמצעות call (או apply)