This translation is incomplete. Please help translate this article from English.

לאחר שסיימנו עם התיאוריה והפרטים של OOJS, המאמר הזה נועד להראות כיצד ליצור מחלקות אובייקטים ״ילדים״ (constructors) אשר יורשים מההורים שלהם. אנו גם נציג מעין עצות מתי נרצה להשתמש ב-OOJS ונסתכל כיצד ״מחלקות״ מתבצעות בסינטקס המודרני של ECMAScript.

ידע מוקדם: Basic computer literacy, a basic understanding of HTML and CSS, familiarity with JavaScript basics (see First steps and Building blocks) and OOJS basics (see Introduction to objects).
מטרה: להבין כיצד זה אפשרי להחיל הורשה ב- JavaScript

Prototypal inheritance

עד עכשיו ראינו קצת הורשה בפעולה - ראינו כיצד prototype chains עובדות וכיצד מתודות ופרופ׳ מורשים בהמשך השרשרת. אבל זה היה בעיקר עם פונקציות מובנות של הדפדפן. כיצד אנחנו יכולים ליצור אובייקט ב-JavaScript אשר יורש מאובייקט אחר?

דוגמא:

ראשית, עשו עותק מקומי של הקובץ או ראו אותו כדף אינטרנט. בקוד זה אתם תראו את ה-Person() constructor שהשתמשנו בו לאורך המודול, עם שינוי קל - הגדרנו רק את ה-properties בתוך ה-constructor.

function Person(first, last, age, gender, interests) {
  this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
  this.interests = interests;
};

כל המתודות כולן מוגדרות בתוך ה-constructor's prototype. לדוגמא:

Person.prototype.greeting = function() {
  alert('Hi! I\'m ' + this.name.first + '.');
};

תשומת לבל: בקוד המקור אתם גם תראו מתודות נוספות שמוגדרות, ()bio ו-()farewell. אנחנו נראה בהמשך כיצד מתודות אלו יכולות להיות מורשות ל-constructors אחרים.

נניח ואנחנו רוצים ליצור מחלקת של Teacher, כמו זו שהסברנו בתחילת המודול לגבי תכנות מונחה עצמים, ומחלקה זו יורשת את כל הפרופ׳ והמתודות של Person, אבל גם כוללת:

  1. property חדש בשם subject — אשר יכיל את נושאי הלימוד שהמורה מלמד.
  2. מתודה ()greeting מעודכנת, אשר תהיה יותר רשמית מהמתודה ()greeting הרגילה.

הגדרה של ה-constructor function בשם ()Teacher

הדבר הראשון שאנחנו צריכים לעשות הוא להגדיר את ה-constructor בשם ()Teacher - הוסיפו את הקוד הבא מתחת לקוד הנוכחי:

function Teacher(first, last, age, gender, interests, subject) {
  Person.call(this, first, last, age, gender, interests);

  this.subject = subject;
}

זה נראה מאוד דומה ל-constructor בשם Person, אבל משהו פה שונה, משהו שלא ראינו עד כה - פונקציה בשם ()call.

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

הפרמטר הראשון שהפונקציה הזו מקבלת מכיל את הערך של this שאנחנו נרצה להשתמש בו כאשר אנחנו מריצים את הפונקציה, והפרמטרים האחרים אלו פרמטרים שאמורים להיות מועברים לפונקציה עצמה כאשר היא מופעלת.

אנחנו רוצים שה-Teacher() constructor יקבל את אותם פרמטרים כמו שה-Person() constructor שהוא יורש ממנו מקבל, ולכן אנחנו מציינים אותם כפרמטרים בתוך ההפעלה של ה-()call.

השורה האחרונה בתוך ה-constructor פשוט מגדירה property בשם subject אשר ייחודי למורים, שאנשים רגילים מ-()Person לא מקבלים.

יכלנו גם לרשום זאת כך, ללא שימוש ב-()call:

function Teacher(first, last, age, gender, interests, subject) {
  this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
  this.interests = interests;
  this.subject = subject;
}

אבל בקוד למעלה זו הגדרה מחדש של ה-properties כחדשים, לא כאלו שיורשים מ- ()Person, אז זה סותר את מה שאנחנו מנסים לעשות - זה לא מוריש אלא זה יוצר חדשים. מה גם שזה לוקח יותר שורות קוד.

ירושה מ-constructor שלא מקבל פרמטרים

שימו לב שאם ה-constructor שאנחנו יורשים ממנו לא מקבל את הערכים של ה-property שלו מקבלים מפרמטרים, אז אנחנו לא צריכים לציין אותם כפרמטרים בתוך ה-()call. לדומא, אם היה לנו משהו פשוט כמו זה: :

function Brick() {
  this.width = 10;
  this.height = 20;
}

אנחנו יכולים לרשת את ה-properties של ה-width ואת ה-height, באמצעות שימוש בקוד הרשום מטה:

function BlueGlassBrick() {
  Brick.call(this);

  this.opacity = 0.5;
  this.color = 'blue';
}

שימו לב שאנחנו רק צריכים לציין את ה-this בתוך ה-()call, ללא פרמטרים נוספים, שכן אנחנו לא יכולים יורשים שום דבר מ-()Brick שהוא קיבל דרך פרמטרים.

קביעת ה-prototype וה-constructor של ()Teacher

עד עכשיו הכל עובד תקין, אך יש לנו בעיה. הגדרנו אמנם constructor חדש, ויש לו את ה-property בשם prototype, אשר כברירת מחדל מכיל רק הפנייה ל-constructor function עצמה.

הוא לא מכיל שום מתודות של ה-property בשם prototype של ה-Person constructor. על מנת לראות זאת, הכניסו (Object.getOwnPropertyNames(Teacher.prototype לתוך הקונסולה.

לאחר מכן הכניסו זאת שוב, והחליפו את המילה Teacher במילה Person. ה-constructor החדש לא יורש את אותן מתודות. על מנת לראות זאת, השוו את הפלט של Person.prototype.greeting והפלט של Teacher.prototype.greeting. אנחנו צריכים לגרום ל-()Teacher לירוש מתודות שמוגדרות ב-prototype של ()Person. איך עושים זאת?

  1. הוסיפו את הקוד הבא מתחת לקוד שהוספתם לפני כן:
    Teacher.prototype = Object.create(Person.prototype);
    כאן ()create מגיע שוב לעזרה. במקרה הזה, אנחנו משתמשים בו על מנת ליצור אובייקט חדש שיהיה הערך של Teacher.prototype. האובייקט החדש הוא בעל Person.prototype כאובייקט ה-prototype שלו, ולכן, הוא יירש ממנו אם וכאשר יצטרך, את כל המתודות שזמינות ב-Person.prototype.
  2. אנחנו צריכים לעשות משהו נוסף לפני שנמשיך הלאה. לאחר שהוספנו את השורה הקודמת, ה-property בשם constructor שווה כעת ל- ()Person, מכיוון שאנחנו הרגע הגדרנו את Teacher.prototype אליו. נסו לשמור את הקוד ולהעלות את הדף בדפדפן וראו זאת על ידי הקלדת Teacher.prototype.constructor בקונסולה.
  3. זה יכול להיות בעיה, ולכן אנחנו צריכים לתקן זאת. ניתן לעשות זאת באמצעות הקלדת הקוד הבא מתחת לקוד הנוכחי שלנו.:
    Object.defineProperty(Teacher.prototype, 'constructor', { 
        value: Teacher, 
        enumerable: false, // so that it does not appear in 'for in' loop
        writable: true });
  4. כעת, אם תשמרו ותרעננו את הדף, הקלדת Teacher.prototype.constructor לקונסולה אמורה להחזיר לכם ()Teacher, כפי שרצינו, ובנוסף אנחנו יורשים מ-()Person.

הענקה ל- Teacher() פונקציית/מתודת greeting() חדשה

אנו רוצים להגדיר פונקציית ()greeting חדשה בתוך ה-Teacher() constructor שלנו.

הדרך הפשוטה ביותר לעשות זאת היא להגדיר זאת בתוך ה-prototype של ()Teacher - הוסיפו את הקוד הבא מתחת לקוד הנוכחי:

Teacher.prototype.greeting = function() {
  var prefix;

  if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
    prefix = 'Mr.';
  } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
    prefix = 'Mrs.';
  } else {
    prefix = 'Mx.';
  }

  alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
};

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

נסו את הדוגמא הבאה:

כעת שהכנסו את כל הקוד, נסו ליצור אובייקטים חדשים מ-()Teacher באמצעות הכנסת הקוד הבא מתחת לקוד הנוכחי:

var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');

כעת, שמרו את הדף ורעננו ונסו לגשת לפרופ׳ והמתודות של האובייקט teacher1 החדש שלנו. לדוגמא:

teacher1.name.first;
teacher1.interests[0];
teacher1.bio();
teacher1.subject;
teacher1.greeting();
teacher1.farewell();

הכל אמור לעבוד כשורה. השורות 1,2,3 ו-6 משתמשות במתודות/פרופ׳ שנורשו מה-Person() constructor שלנו. השורה 4 משתמשת בפרופ׳ שזמין רק באמצעות ה-Teacher() constructor שלנו. שורה 5 הייתה יכולה להיות מורשת מ-()Person, אבל מכיוון של-()Teacher יש את אותה מתודה, אז היא ניגשת למתודה שנמצאת ב-()Teacher.

לתשומת לב: אם נתקלתם בבעיות, נסו להשוות את הקוד שלכם ל קוד הסופי או ראו אותו כ דף אינטרנט.

הטכניקות שראינו עד כה, אינן היחידות ליצירת מחלקות ירושה ב-JavaScript, אבל הן עובדות בסדר, הן נותנות לכם הבנה כיצד להחיל ירושה ב-JavaScript.

אולי תהיו מעוניינים לבדוק חלק מהאפשרויות החדשות ש-ECMAScript מאפשרת לנו, בצורה ״נקייה״ יותר, באמצעות Classes. אנו נגע בדרך זו בהמשך. שימו לב כי דרך חדשה זו לא תומכת בכל הדפדפנים. כל יתר הדרכים שראינו תומכות בדפדנים ישנים גם כמו IE9 ומוקדם יותר ויש דרכים גם לאפשר תמיכה לדפדפנים ישנים יותר.

דרך מקובלת היא להשתמש בספריית JavaScript - לפופולריות שביניהן יש סט של פונקציונליות שזמין עבור ביצוע הורשה בצורה פשוטה ומהירה. אחת מהן היא CoffeeScript אשר מאפשרת class ,extends לדוגמא.

המשך תרגול

במאמר שלנו בנושא OOP theory section, כללנו גם מחלקת Student באופן עקרוני, אשר יורשת תכונות מ-Person וגם יש לה מתודת ()greeting שונה מזו של Person ומשל Teacher. נסתכל כיצד ה-greeting של התלמידים אמורה להיות וננסה לבנות constructor בשם ()Student משלנו, אשר יורש את כל התכונות מ-()Person ומחיל מתודת ()greeting שונה.

שימו לב: אם אתם נתקלים בבעיות, ראו את הגרסה הסופית או כדף אינטרנט .

סיכום בנושא תכונות האובייקט

על מנת לסכם, יש לנו בעיקרון שלוש סוגים של property/method לדאוג להם:

  1. אלו המוגדרים בתוך ה-constructor function וניתנים לאובייקטים שנוצרים באמצעות ה- this. אלו בעיקרון מאוד קלים לאיתור - בתוך הקוד שלנו, אלו התכונות שמוגדרות בתוך ה-constructor באמצעות this.x = x, והם זמינים רק עבור האובייקטים שנוצרים (בדרך כלל נוצרים באמצעות ה-constructor ושימוש במילה השמורה new, לדוגמא: ()var myInstance = new myConstructor.
  2. אלו המוגדרים ישרות על ה-constructor עצמם, ואלו זמינות רק על ה-constructor. הם לרוב יהיו זמינים רק אובייקטים מובנים של הדפדפן, ואנחנו יכולים לזהות שהם קשורים באופן ישירות ל-constructor ולא למופע אובייקט. לדוגמא ()Object.keys.
  3. ואלו המוגדרים על הפרופ׳ בשם prototype של ה-constructor, אשר נורשים על ידי כל מופעי האובייקט שנוצרים או אובייקטים שיורשים מהם. זה כולל כל תכונה שמוגדרת ב-property בשם prototype של ה-Constructor. לדוגמא: ()myConstructor.prototype.x.

אם אתם לא בטוחים מה זה מה, אל תדאגו, אתם תכירו אותם יותר לעומק במהלך הדרך והמשך הקריירה שלכם ככל שתתמודדו איתם.

ECMAScript 2015 Classes

ECMAScript 2015 הציגה מעין סינטקס חדש בשם class syntax ל- JavaScript כדרך חדשה לרשום מחלקות לשימוש חוזר, באמצעות סינטקס פשוט ונקי יותר, אשר דומה יותר ל-classes ב-C++ או ב-Java. בחלק הזה של המאמר אנחנו נמיר את הדוגמאות מלמעלה מ-prototypal inheritance ל-classes, על מנת להראות לכם איך לעשות שימוש-classes.

לתשומת לב: דרך חדשה זו של כתיבת classes נתמכת בכל הדפדפנים המודרניים, אבל זה עדיין חשוב להבין את ה-prototypal inheritance במקרה ותיתקלו בפרוייקט שדורש תמיכה בדפדפן שאינו תומך בסינטקס של classes - הידוע מבין כולם הוא Internet Explorer.

נסתכל על הדוגמא שלנו של Person כתובה בצורת classes:

class Person {
  constructor(first, last, age, gender, interests) {
    this.name = {
      first,
      last
    };
    this.age = age;
    this.gender = gender;
    this.interests = interests;
  }

  greeting() {
    console.log(`Hi! I'm ${this.name.first}`);
  };

  farewell() {
    console.log(`${this.name.first} has left the building. Bye for now!`);
  };
}

ההצהרה באמצעות המילה השמורה class מצהירה בעצם בשאנחנו רוצים ליצור class חדשה. בתוך הבלוק הזה שבין {}, אנחנו מגדירים את התכונות של אותה מחלקה:

  • המתודה ()constructor מגדירה את ה-constructor function שמייצגת את ה-class Person שלנו.
  • ()greeting ו- ()farewell הם class methods. כל מתודה שאנחנו נרצה לייחס אותה למחלקה מוגדרת בתוך ה-class, לאחר ה-constructor. בדוגמא הזו, השתמשנו ב- template literals מאשר בשרשור מחרוזות על מנת שהקוד שלנו יהיה קריא יותר.

כעת אנחנו יכולים ליצור מופעי אובייקט חדשים באמצעות שימוש באופרטור new operator, באותה הדרך שעשינו בעבר:

let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);
han.greeting();
// Hi! I'm Han

let leia = new Person('Leia', 'Organa', 19, 'female', ['Government']);
leia.farewell();
// Leia has left the building. Bye for now

לתשומת לב: מאחורי הקלעים, ה-classes שלנו מומרים ל-prototypal Inheritance models - זהו רק syntactic sugar - שזה אומר דרך אחרת מבחינת סינטקס לעשות דבר זהה, אך לא משהו אחר. יחד עם זאת, אין ספק שזו דרך פשוטה יותר להעניק הורשה.

הורשה עם class syntax

למעלה יצרנו class על מנת לתאר person. יש לנו סט של תכונות שזהות לכל האנשים. בחלק זה אנחנו ניצור את ה-class המיוחד של Teacher, ונגרום לו לירוש מ-Person באמצעות שימוש בסינטקס class החדש. זה נקרא יצירת subclass או ביצוע subclassing.

על מנת ליצור subclass אנחנו יכולים להשתמש במילה השמורה extends על מנת להגיד ל-JavaScript איזו class אנחנו מתבססים עליה ביצירת ה-class החדשה:

class Teacher extends Person {
  constructor(subject, grade) {
    this.subject = subject;
    this.grade = grade;
  }
}

אך יש קאצ׳ קטן:

שלא כמו ה-Constructor function, שבהן האופרטור new operator היה עושה את האתחול של המילה this לאובייקט חדש, פה זה לא קורה בצורה אוטומטית בעבור המחלקה שמוגדרת באמצעות המילה extends, כלומר עבור ה-sub-classes.

ולכן הרצה שלהקוד למעלה יציג לנו שגיאה:

Uncaught ReferenceError: Must call super constructor in derived class before
accessing 'this' or returning from derived constructor

למחלקות משנה, sub-classes, ההגדרה של this בעבור אובייקט חדש, תהיה תמיד תלויה ב-parent class constructor, כלומר ב-constructor function של ה-class שממנה אנחנו מתרחבים (extending).

כאן, אנחנו מרחיבים את המחלקה Person- המחלקת משנה בשם -Teacher היא בעצם extension - הרחבה - של המחלקה Person. אז עבור Teacher האתחול של this מתבצע על ידי ה-constructor Person.

על מנת לקרוא ל-constructor ה-parent, אנחנו צריכים להשתמשש באופרטור ()super , כך:

class Teacher extends Person {
  constructor(subject, grade) { 
    super();              // Now `this` is initialized by calling the parent constructor.
    this.subject = subject;   
    this.grade = grade; 
  }
}

אין שום סיבה שתהיה לנו sub-class אם היא לא יורשת מאפיינים מה-parent class.
זה רעיון טוב אז שהאופרטור ()super  גם מקבל ארגומנטים בעבור ה- parent constructor.

כאשר אנחנו מסתכלים על ה- Person constructor,  אנחנו יכולים לראות שיש לו את הבלוק קוד הבא בתוך ה-constructor שלו:

 constructor(first, last, age, gender, interests) { 
   this.name = {   
     first,   
     last   
   }; 
   this.age = age; 
   this.gender = gender;   
   this.interests = interests; 
} 

מאחר והאופרטור ()super הוא בעצם ה-parent class constructor, העברה של הארגומנטים הרלוונטיים של המחלקת אם, גם תאתחל את הפרופ׳ במחלקת משנה שלנו, ותירש אותם: 

class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);

    // subject and grade are specific to Teacher
    this.subject = subject;
    this.grade = grade;
  }
}

כעת, כשיוצרים מופעי אובייקט של Teacher, אנחנו יכולים לקרוא למתודות ופרופ׳ שהוגדרו גם ב-Teacher וגם ב-Person:

let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
snape.greeting(); // Hi! I'm Severus.
snape.farewell(); // Severus has left the building. Bye for now.
snape.age // 58
snape.subject; // Dark arts

לתשומת לב: אתם יכולים למצוא את הדוגמא ב-GitHub ב- es2015-class-inheritance.html  או כ-דף אינטרנט.

Getters ו- Setters

יהיו פעמים שאנחנו נרצה לשנות את הערכים של מאפיין בתוך השאנחנו יוצרים או שאנחנו לא נדע מהו הערך הסופי שאותו מאפיין יקבל. אם נסתכל על הדוגמא שלנו Teacher, יכול להיות מצב שאנחנו לא נדע מה הנושא שהמורה מלמד לפני שאנחנו יוצרים אותו או שהנושא יכול להשתנות במהלך התקופה.

במקרים כאלו אנחנו נוכל להשתמש ב-getters ו-setters.

נשפר את Teacher class עם  getters ו-setters. המחלקה מתחילה בדיוק כמו שראינו אותה בדוגמא האחרונה.

 getters ו-setters עובדים בזוגות. getter מחזיר את הערך הנוכחי של משתנה וה-setter הבן זוג שלו משנה את הערך של המשתנה למה שה-setter יגדיר. 

המחלקה Teacher החדשה תיראה כך:

class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);
    // subject and grade are specific to Teacher
    this._subject = subject;
    this.grade = grade;
  }

  get subject() {
    return this._subject;
  }

  set subject(newSubject) {
    this._subject = newSubject;
  }
}

במחלקה למעלה יש לנו getter ו-setter בעבור הפרופ׳ subject. אנחנו משתמשים בסימן _ על מנת ליצור ערך נפרד שבו נאחסכן את השם של הפרופ׳. אם לא נעשה זאת בצורה הזה, אנחנו נקבל שגיאות בכל פעם שנקרא ל-get או ל-set. בנקודה זו: 

  • על מנת לקבל את הערך הנוכחי של הפרופ׳ _subject של האובייקט snape, אנחנו יכולים להשתמש במתודת snape.subject getter.
  • על מנת להשים ערך חדש לפרופ׳ _subject אנחנו יכולים להשתמש במתודת snape.subject="new value" setter. 

הדוגמא למטה מראה את השימוש באפשרויות האלו: 

// Check the default value
console.log(snape.subject) // Returns "Dark arts"

// Change the value
snape.subject="Balloon animals" // Sets _subject to "Balloon animals"

// Check it again and see if it matches the new value
console.log(snape.subject) // Returns "Balloon animals"

לתשומת לב : תוכלו למצוא את es2015-getters-setters.html ב-GitHub, או כדף אינטרנט.

מתי אנחנו נשתמש בהורשה ב-JavaScript?

רוב הסיכויים שלאחר קריאת המאמר הזה, אתם בטח חושבים לעצמכם ״טוב, זה מסובך מאוד״. אתם צודקים. הורשה ואבי טיפוס הינם חלק מההיבטים המורכבים ביותר של JavaScript, אבל הרבה מעוצמתה של השפה והגמישות שלה מגיע מתוך המבנה של האובייקטים והירושה שלהם, וזה שווה להכיר ולהבין כיצד התהליכים הללו מתרחשים. 

בדרך מסויימת, אנחנו משתמשים בהורשה כל הזמן. בכל פעם שאנחנו משתמשים במאפיינים שונים של Web API או בפרופ׳/מתודות שהוגדרו באובייקט מובנה של הדפדפן (built-in browser object) על מחרוזות, מערכים וכד׳ אנחנו באופן עקיף משתמשים בירושה. 

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

לתשומת לב: לאור הדרך שבה JavaScript עובדת עם שרשרת אבי הטיפוס (prototype chain) וכד׳ - השיתוף של פונקציונליות בין אובייקטים נקרא לרוב delegation - ״האצלה״. אובייקטים מיוחדים ״מאצילים״ פונקציונליות לאובייקטים שנוצרים.  

כאשר אנחנו משתמשים בהורשה, ההמלצה היא שלא יהיו יותר מדי רמות של הורשה, ושתמיד נעקוב איפה אנחנו מגדירים את המתודות והפרופ׳. זה אפשרי להתחיל לכתוב קוד שבאופן זמני משנה את ה-prototypes של האובייקטים המובנים של הדפדפן (built-in browser objects), אבל אין לעשות זאת אלא אם כן יש לנו סיבה מאוד טובה. יותר מדי הורשה יכולה להוביל לבלבול אינסופי ולשגיאות בקוד. 

באופן אולטמטיבי, אובייקטים הם פשוט תבנית אחרת של שימוש חוזר בקוד, כמו פונקציות ולולאות, עם הכללים והיתרונות שלהם. אם אתם מוצאים את עצמכם יוצרים משתנים ופונקציות הקשורים אחד לשני ואתם רוצים לעקוב ולארוז אותם יחד בצורה מסודרת, אובייקט הוא רעיון טוב. אובייקטים גם שימושיים מאוד כשאנחנו רוצים להעביר ריכוז של מידע ממקום אחד למקום שני. את שני הדברים הללו ניתן להשיג ללא שימוש ב-constructors או ב-inheritance. אם אנחנו צריכים רק מופע אחד של אובייקט, כנראה יהיה עדיף פשוט להשתמש ב-inheritance ואין צורך בירושה.

אלטרנטיבות להרחבה של שרשרת ההורשה 

ב-JavaScript, יש מספר דרכים שונות להרחבה של ה-prototype של אובייקט חוץ מאלו שראינו במאמר זה. להרחבה בנושא, ראו את הדף שלנו בנושא Inheritance and the prototype chain.

לסיכום

מאמר זה נועד לסקור את יתרת הנושא של OOJS וסינטקס נוסף שאנחנו חושבים שאתם צריכים לדעת. בנקודה זו אתם אמורים להבין את ההיבטים של אובייקטים ב-JavaScript ואת הבסיס של תכנות מונחה עצמים (OOP), אביט טיפוס, שרשרת אבי-טיפוס, הורשה באמצעות אבי-טיפוס, כיצד ליצור מחלקות (classes), מופעי אובייקטים, הוספת מאפיינים למחלקות, יצירת מחלקות משנה שיורשות ממחלקות אחרות ועוד. 

במאמר הבא אנחנו נגע כיצד לעבוד עם (JavaScript Object Notation (JSON, פורמט מקובל להעברת מידע.

ראו גם

  • ObjectPlayground.com — אתר ללמידה אינטראקטיבית של בנושא אובייקטים.
  • Secrets of the JavaScript Ninja, פרק 7 - ספר טוב בנושא עקרונות מתקדמים של JavaScript של John Resig, Bear Bibeault, ו-Josip Maras. פרק 7 מכסה את ההיבטים של אבי טיפוס והורשה. 

במודול זה

Document Tags and Contributors

Contributors to this page: ItzikDabush
Last updated by: ItzikDabush,