על המתודות call, apply ו-bind ב-JavaScript
המתודות call, apply ו-bind ב-JavaScript הן מתודות שימושיות מאוד אך ההבדל ביניהן עלול לבלבל.
אז למה הן משמשות ומה ההבדלים ביניהן? במאמר הבא.
דומות אבל שונות
באופן כללי, המתודות call, apply ו-bind ב-JavaScript משמשות לביצוע פונקציה כאשר ה-this בתוכה משתנה בהתאם לקריאה הנוכחית, אך כל אחת מהן שונה במקצת מהאחרת.
()call
המתודה call קוראת לפונקציה ומבצעת אותה באופן מיידי. הארגומנט הראשון שהיא תקבל יהיה האובייקט שה-this בפונקציה יצביע עליו.
נשמע מאוד מסובך, לא? לא 🙂
דוגמה קצרה שתבהיר עד כמה זה פשוט:
let sayHello = function() {
console.log('Hello! My name is ' + this.name);
}
let david = {
name: 'David'
}
sayHello.call(david);
הפלט אל ה-console:

אז מה קרה כאן בעצם?
בדוגמה הנ"ל ישנה פונקציה בשם sayHello, הפונקציה מדפיסה ל-console משפט הכולל בתוכו את ה-property בשם name של האובייקט שמועבר לפונקציה.
לאחר מכן, בשורה מספר 5, נוצר אובייקט פשוט בשם david עם ה-property בשם name כמובן והערך david מן הסתם.
בשורה האחרונה, על ידי שימוש במתודה call, בוצעה הוצאה אל הפועל של הפונקציה sayHello כאשר הארגומנט שהועבר אליה היה האובייקט david ולכן ה-this במקרה זה הצביע על האובייקט…david, ברור.
דוגמה נוספת:
let sayHello = function() {
console.log('Hello! My name is ' + this.name);
}
let david = {
name: 'David'
}
let maria = {
name: 'Maria'
}
sayHello.call(maria);
במקרה הבא למשל, this מצביע על האובייקט בשם maria ולכן הפלט אל הקונסול יהיה:

ארגומנטים נוספים
ניתן להעביר גם ארגומנטים נוספים אל המתודה:
let sayHello = function(country) {
console.log('Hello! My name is ' + this.name + ' and I\'m from ' + country);
}
let david = {
name: 'David'
}
let maria = {
name: 'Maria'
}
sayHello.call(maria, 'Italy');
הארגומנט הראשון תמיד יהיה האובייקט ש-this יצביע עליו ולאחר מכן יגיעו הפרמטרים שהפונקציה שבה נשתמש מצפה לקבל, במקרה זה, הפרמטר שהפונקציה sayHello מצפה לקבל הוא country והערך שלו הוא Italy כמובן.
הפלט:

שימוש במתודה שנמצאת באובייקט אחר
ניתן להשתמש במתודה call גם כאשר המתודה שנרצה להשתמש בה נמצאת באובייקט אחר לגמרי:
let david = {
name: 'David',
country: 'Germany',
sayHello: function() {
console.log('Hello! My name is ' + this.name + ' and I\'m from ' + this.country);
}
};
let maria = {
name: 'Maria',
country: 'Italy'
};
david.sayHello.call(maria);
מה שקרה כאן זה שהאובייקט maria השתמש במתודה sayHello אשר קיימת באובייקט david בכלל, קולטים? 🙂
הפלט זהה לפלט מהדוגמה הקודמת.
חשוב לשים לב, כאשר משתמשים במתודה שקיימת באובייקט, אין לשכוח לציין את שם האובייקט לפני שם המתודה:

()apply
המתודה apply דומה מאוד למתודה call, ההבדל הוא שהמתודה apply מקבלת את הארגומנטים כמערך ולא באופן נפרד.
דוגמה:
let sayHello = function(age, country) {
console.log('Hello! My name is ' + this.name + ', I\`m ' + age + ' years old and I\'m from ' + country);
}
let david = {
name: 'David'
}
sayHello.apply(david, [29, 'Germany']);
בדוגמה הנ"ל המתודה sayHello מצפה לקבל 2 ארגומנטים, אבל מאחר ונעשה שימוש ב-apply ולא ב-call הארגומנטים יועברו כמערך ולא באופן מופרד.
הפלט:

()bind
אז מהי המתודה bind?
המתודה bind מאוד דומה למתודה call אך עם שינוי משמעותי אחד – היא לא מייצרת קריאה אל הפונקציה באופן מיידי.
דוגמה:
let sayHello = function(age, country) {
console.log('Hello! My name is ' + this.name + ', I\`m ' + age + ' years old and I\'m from ' + country);
}
let david = {
name: 'David'
}
let davidSayHello = sayHello.bind(david, 29, 'Germany');
davidSayHello();
הפלט יהיה זהה לפלט מהדוגמה הקודמת מאחר וחוץ ממועד ביצוע הפונקציה לא השתנה דבר.
חשוב לשים לב, בשורה מספר 9 המשתנה בשם davidSayHello מקבל לתוכו את הפונקציה.
הקריאה עצמה מתבצעת רק בשורה מספר 10.
שורה קצרה שתוכיח זאת:
console.log(davidSayHello);
והפלט שהתקבל:

ניתן לראות בבירור כי davidSayHello מכיל בתוכו אך ורק את הפונקציה עצמה, הקריאה עוד לא התבצעה בשלב זה.
המתודה bind מאפשרת גמישות שאין ב-call וה-apply, העובדה שהיא לא מבצעת קריאה לפונקציה באופן מיידי מאפשרת להשתמש בפונקציה במועד מאוחר יותר ואף מספר פעמים במידת הצורך.
בהצלחה!
נהנת ממאמר זה? הירשם לרשימת התפוצה וקבל עדכונים על מאמרים חדשים!
רק רגע! :)
כשאני לא כותב פוסטים ב-CodeBrain אני מספק שרותי פיתוח, ייעוץ והדרכה.
אם נראה לך שאני האיש המתאים עבורך, כדאי שנדבר :)
תודה החכמתי
תודה זה הסבר מעולה
הסבר מצוין!
תודה רבה על כל הבלוג הזה!!!
אחד האתרים שמסביר את ההבדלים בצורה הכי ברורה וקלה שיש!
תודה רבה!
הסבר מצוין, שאפו
שמח שאהבת, תודה!
מהנה וקליל. תודה!
אחד הטובים!!
תודה רבה!