4.1 קלוז׳רים וסקופ תרגול
תרגול - קלוז׳רים וסקופ¶
תרגיל 1 - חידות scope chain¶
מה ידפיס כל אחד מקטעי הקוד הבאים? ענו בלי להריץ, ואז בדקו.
חידה א:¶
let x = 1;
function a() {
let x = 2;
function b() {
console.log(x);
}
return b;
}
const fn = a();
fn();
חידה ב:¶
let count = 0;
function increment() {
count++;
console.log(count);
}
function reset() {
let count = 0;
console.log(count);
}
increment();
increment();
reset();
increment();
חידה ג:¶
function outer() {
let x = 10;
function middle() {
let y = 20;
function inner() {
let z = 30;
console.log(x + y + z);
}
x = 100;
inner();
}
middle();
}
outer();
תרגיל 2 - מונה עם closure¶
כתבו פונקציה createCounter שמקבלת ערך התחלתי ומחזירה אובייקט עם הפונקציות הבאות:
increment()- מעלה את הערך ב-1 ומחזירה את הערך החדשdecrement()- מורידה את הערך ב-1 ומחזירה את הערך החדשgetValue()- מחזירה את הערך הנוכחיreset()- מחזירה את הערך לערך ההתחלתי
const counter = createCounter(10);
console.log(counter.increment()); // 11
console.log(counter.increment()); // 12
console.log(counter.decrement()); // 11
console.log(counter.getValue()); // 11
counter.reset();
console.log(counter.getValue()); // 10
ודאו שלא ניתן לגשת ישירות למשתנה הפנימי מבחוץ.
תרגיל 3 - פונקציית memoize¶
כתבו פונקציה memoize שמקבלת פונקציה ומחזירה גרסה ממואיזית שלה. הגרסה הממואיזית שומרת תוצאות קודמות ומחזירה אותן מהמטמון אם אותם ארגומנטים כבר חושבו.
function slowSquare(n) {
console.log("Computing...");
return n * n;
}
const fastSquare = memoize(slowSquare);
console.log(fastSquare(5)); // "Computing..." -> 25
console.log(fastSquare(5)); // 25 (no "Computing..." - from cache)
console.log(fastSquare(3)); // "Computing..." -> 9
console.log(fastSquare(5)); // 25 (from cache)
בונוס: הוסיפו מתודה cache.clear() שמנקה את המטמון.
תרגיל 4 - משתנים פרטיים¶
צרו פונקציה createPasswordManager שמחזירה אובייקט לניהול סיסמה:
setPassword(newPassword)- מגדירה סיסמה חדשה (מינימום 8 תווים, אחרת מחזירהfalse)checkPassword(attempt)- בודקת אם הסיסמה נכונה ומחזירהtrue/falsegetHint()- מחזירה את שני התווים הראשונים של הסיסמה ואחריהם כוכביות
הסיסמה עצמה חייבת להיות בלתי נגישה מבחוץ.
const pm = createPasswordManager();
pm.setPassword("abc"); // false (too short)
pm.setPassword("mySecret123"); // true
pm.checkPassword("wrong"); // false
pm.checkPassword("mySecret123"); // true
pm.getHint(); // "my*********"
תרגיל 5 - closure בלולאה¶
חלק א - זהו את הבאג¶
מה ידפיס הקוד הבא ולמה?
const buttons = [];
for (var i = 0; i < 5; i++) {
buttons.push({
label: `Button ${i}`,
click: function() {
console.log(`Clicked button ${i}`);
}
});
}
buttons[0].click();
buttons[2].click();
buttons[4].click();
חלק ב - תקנו את הבאג¶
תקנו את הקוד בשתי דרכים שונות:
1. באמצעות let
2. באמצעות IIFE
תרגיל 6 - תבנית המודול - module pattern¶
צרו מודול TaskManager באמצעות IIFE ו-closures שמנהל רשימת משימות:
addTask(title)- מוסיפה משימה חדשה עםidייחודי (אוטומטי) ו-done: falsecompleteTask(id)- מסמנת משימה כ-done: trueremoveTask(id)- מוחקת משימהgetTasks()- מחזירה עותק של כל המשימותgetPending()- מחזירה רק משימות שלא הושלמוgetStats()- מחזירה אובייקט עם{ total, done, pending }
TaskManager.addTask("Learn closures");
TaskManager.addTask("Practice exercises");
TaskManager.addTask("Build project");
console.log(TaskManager.getStats()); // { total: 3, done: 0, pending: 3 }
TaskManager.completeTask(1);
console.log(TaskManager.getPending().length); // 2
console.log(TaskManager.getStats()); // { total: 3, done: 1, pending: 2 }
תרגיל 7 - createMultiplier ושרשרת פונקציות¶
חלק א¶
כתבו פונקציה createMultiplier(factor) שמחזירה פונקציה שמכפילה מספר ב-factor:
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
חלק ב¶
כתבו פונקציה compose(...fns) שמקבלת מספר כלשהו של פונקציות ומחזירה פונקציה חדשה שמפעילה אותן בזו אחר זו (מימין לשמאל):
const double = createMultiplier(2);
const addOne = (x) => x + 1;
const square = (x) => x * x;
const transform = compose(addOne, double, square);
// transform(3) should compute: square(3) -> 9, double(9) -> 18, addOne(18) -> 19
console.log(transform(3)); // 19
console.log(transform(5)); // 51
הסבירו: איפה ה-closure בפונקציה compose?