באחד המאמרים הקודמים דיברנו על פונקצית למדא. במאמר הזה אכסה כמה דברים שהם קצת יותר קלילים ונחמדים וסביר להניח שתיישמו אותם מייד.
ערכים דיפולטיביים לפונקציות
אחד הדברים שתמיד הפריעו לי ב-JavaScript הוא שאי אפשר לתת ערכים דיפולטיביים למשתנים. למשל, אם היתה לי פונקציה שמקבלת שלושה ארגומנטים, לא יכולתי לקבוע שאם המשתמש קורא לה עם ארגומנט אחד, שני הארגומנטים יקבלו ערכים דפולטיביים. תמיד הייתי צריך להשתמש במשהו עקום כזה:
function myFunction (x, y, z) {
if (y === undefined) {
y = 'moshe';
}
if (z === undefined) {
z = 'yaakov';
}
};
כלומר הייתי בודק את הארגומנטים הנוספים ואם הם היו undefined, אז הייתי מכניס להם ערכים דיפולטיביים. מטופש ומציק. טוב, לא עוד! עם ECMAScript 6 אפשר לקבוע את הכל.
function myFunction (x, y = 'moshe', z = 'yaakov') {
console.log(x); //ran
console.log(y); //moshe
console.log(z); //yaakov
};
myFunction('ran');
אתם מוזמנים להשתעשע בעצמכם עם זה.
See the Pen ES6 – default variables by Ran Bar-Zik (@barzik) on CodePen.
REST Parameters
עם ECMAScript 6, זה גם פשוט יותר לדעת מה הארגומנטים הנוספים שהמשתמש הכניס. כפי שאנחנו יודעים, ב-JavaScript אפשר להעביר כמה ארגומנטים שרוצים לפונקציה. השאלה היא איך מוצאים אותם. בעבר היינו צריכים לעשות משהו כזה:
function myFunction(x) {
var additionalArgs = Array.prototype.slice.call(arguments, 1);
console.log(additionalArgs);
};
myFunction('ran', 'moshe', 'yaakov', 'sara'); //["moshe", "yaakov", "sara"]
כאשר את המספר שמופיע ב-slice אני צריך לשנות לפי מספר הארגומנטים. זה מאוד נחמד אבל מסורבל. ב-ECMAScript 6 זה קל ונעים.
function myFunction(x, ...additionalArgs) {
console.log(additionalArgs);
};
myFunction('ran', 'moshe', 'yaakov', 'sara'); //["moshe", "yaakov", "sara"]
כמובן שאפשר לקרוא למשתנה additionalArgs באיזה שם שבא לנו. נחמד, לא?
ECMAScript 6 נותנת לנו דרך לקחת משתנים, אובייקטים או מחרוזות ולהמיר אותם למערכים. זה מאוד מאוד שימושי במיוחד בחיבור. למשל, אם יש לי שני מערכים חביבים, עכשיו אפשר בקלות לחבר אותם:
var params = [ "hello", true, 7 ];
var other = [ 1, 2, ...params ];
console.log(other);// [ 1, 2, "hello", true, 7 ]
Spread Operator
אפשר גם לקחת מערך ולשים אותו בתור משתנים באמצעות spread operator, הנה!
function myFunction(x, y, z) {
console.log(x); //10
console.log(y); //20
console.log(z); //30
}
var args = [10, 20, 30];
myFunction(...args);
See the Pen ES6 Spread Operator by Ran Bar-Zik (@barzik) on CodePen.
ואל תגידו שזה לא פשוט ונחמד. אין כאן מהפיכות גדולות אבל ללא ספק זה הופך את החיים ליותר פשוטים ואת הקוד לפשוט יותר.
עוד משהו נחמד שיש ב-ES6 וקשור חלקית לארגומנטים הוא שיפור קל ביצירת אובייקטים.
למשל, אובייקטים עם משתנים בתוכם. כשאנחנו יוצרים אובייקט, אנחנו היינו, עד עכשיו, צריכים לעשות משהו כזה:
var x = 10;
var y = 20;
obj = { x: x, y: y }; //{x: 10,y: 20}
זה נחמד, אבל עם ES6 אפשר לעבוד קצת יותר יעיל כשאנחנו יוצרים אובייקט. למשל:
var x = 10;
var y = 20;
obj = { x, y }; //{x: 10,y: 20}
כלומר, אם שם התכונות זהה לשם המשתנה, אין צורך להצהיר על שם המשתנה. נכון, מעט איזוטרי אבל קצת יותר נחמד.
כשאנחנו מגדירים שמות של פונקציה, למשל משהו כזה:
obj = {
multiply: function (a, b) {
return a*b;
},
sum: function (x, y) {
return x+y;
}
};
console.log(obj.multiply(2,3)); //6
console.log(obj.sum(2,3)); //5
עם ES6 אני לא חייב לציין את ה-function: במפורש. הנה דוגמה של הקוד הקודם שכתובה לפי ES6.
obj = {
multiply (a, b) {
return a*b;
},
sum (x, y) {
return x+y;
}
};
console.log(obj.multiply(2,3)); //6
console.log(obj.sum(2,3)); //5
זה לא משהו קריטי, אבל משהו בהחלט נחמד.
עוד משהו שהוא קצת ביזארי הוא היכולת שלנו להשתמש בביטויים על מנת לקבוע שמות של תכונות באובייקט כבר בשלב ההגדרה של האובייקט. הנה למשל דוגמה שגם ממחישה את דעתי על הפיצ'ר הזה ותרומתו לקריאות קוד, אפילו שיש סיכוי שזה יהיה שימושי, אני הייתי נמנע ממנו:
obj = {
someProperty: 11,
[ "kakaBaleben" + 10 ]: 42
}; //{kakaBaleben10: 42, someProperty: 11}
עד כאן בנוגע לארגומנטים ולאובייקטים. אין כאן משהו שלא נופל בקטגוריה של סוכר סינטקסי (כלומר לא פיצ'ר שמשנה משהו מהותי אלא שינוי קל בסינטקס כדי להפוך את השפה ליותר קריאה ונעימה) – אבל נחמד ונעים להכיר.