פונקציות חץ
אחת המוזרויות של JavaScript היא המילה השמורה this
. מילה זו מייצגת משתנה שעובר לפונקציה בעת הפעלתה והערך שעובר שם תלוי באופן הפעלת הפונקציה. למי שכותב קוד מונחה עצמים זה היה נורא. הקוד הבא:
function Foo() {
this.value = 10;
}
Foo.prototype.printValue = function() {
console.log('Before. value = ', this.value);
setTimeout(function() {
console.log('After. value = ' + this.value);
}, 10)
};
const f = new Foo();
f.printValue();
מדפיס את הפלט:
Before. value = 10
After. value = undefined
כלומר לכאורה אותו המשתנה this.value
הדפיס ערכים שונים רק בגלל שהפעלנו setTimeout. כמובן שמחשבים לא משקרים והסיבה האמיתית להבדל היא שפונקציית ה callback שהעברנו ל setTimeout נקראה עם ערך אחר ל this. בהתחלה אנשים פתרו בעיות מסוג זה עם הכנסת משתנה חדש:
function Foo() {
this.value = 10;
}
Foo.prototype.printValue = function() {
var that = this;
console.log('Before. value = ', that.value);
setTimeout(function() {
console.log('After. value = ' + that.value);
}, 10)
};
const f = new Foo();
f.printValue();
וזה כבר מדפיס פעמיים את הערך 10 אבל עדיין מבלבל.
אחרי זה שידרגנו ל ES5 ולמדנו להשתמש ב bind:
function Foo() {
this.value = 10;
}
Foo.prototype.printValue = function() {
console.log('Before. value = ', this.value);
setTimeout(function() {
console.log('After. value = ' + this.value);
}.bind(this), 10)
};
const f = new Foo();
f.printValue();
bind אוטומטי
ו ES6 הוסיפה קיצור דרך לכתיב הזה שנקרא פונקציית חץ. פונקציית חץ היא דרך אחרת לכתוב פונקציה כך שבאופן אוטומטי תבצע bind ל this ולכן את אותו הקוד אפשר היום לכתוב כך:
function Foo() {
this.value = 10;
}
Foo.prototype.printValue = function() {
console.log('Before. value = ', this.value);
setTimeout(() => {
console.log('After. value = ' + this.value);
}, 10)
};
const f = new Foo();
f.printValue();
שימו לב שמחקתי את המילה function ואחרי הסוגריים רשמתי את החץ. חוץ מזה הכל נשאר אותו דבר. כמעט.
פונקציות של שורה אחת
קיצור דרך שני של פונקציית החץ מופיע עבור פונקציות של שורה אחת. בפונקציות כאלה המילה return יכולה להפריע בעין. נתבונן בקוד:
const arr = [10, 20, 25, 27, 30];
const odd = arr.filter(function(item) {
return item % 2 !== 0;
});
console.log(odd);
התוצאה היא הדפסת המספרים האי זוגיים מהמערך כלומר 25 ו 27. את אותו הקוד אפשר לכתוב עם פוקנציית חץ מקוצרת באופן הבא:
const arr = [10, 20, 25, 27, 30];
const odd = arr.filter((item) => item % 2 !== 0);
const even = arr.filter(item => item % 2 === 0);
השורה השניה היא פשוט החלפה של הפונקציה המלאה בפונקציית חץ מקוצרת. כאן אחרי החץ אין סוגריים מסולסלים ולכן אנחנו מוגבלים לביטוי יחיד והערך שלו הוא מה שחוזר מהפונקציה (אז לא צריך return
)
השורה השלישית היא פונקצית חץ עוד יותר מקוצרת (מקוצררת אולי?). מסתבר שכשיש רק פרמטר אחר לפונקציית חץ אפשר לוותר על הסוגריים.