לדלג לתוכן

2.4 פונקציות תרגול

תרגול - פונקציות

תרגיל 1 - פונקציות בסיסיות

כתבו את הפונקציות הבאות בשלוש צורות: function declaration, function expression, ו-arrow function.

א. פונקציה isEven שמקבלת מספר ומחזירה true אם הוא זוגי, false אם אי-זוגי.

ב. פונקציה max שמקבלת שני מספרים ומחזירה את הגדול מביניהם.

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

תרגיל 2 - ערכי ברירת מחדל

כתבו פונקציה createEmail שמקבלת:
- to - כתובת (חובה)
- subject - נושא (ברירת מחדל: "No Subject")
- body - תוכן (ברירת מחדל: "")
- priority - עדיפות (ברירת מחדל: "normal")

הפונקציה צריכה להחזיר אובייקט עם כל הפרטים.

בדקו עם:

console.log(createEmail("alice@mail.com"));
console.log(createEmail("bob@mail.com", "Meeting", "See you at 3pm", "high"));
console.log(createEmail("charlie@mail.com", "Hello"));

תרגיל 3 - rest parameters

א. כתבו פונקציה average שמקבלת מספר כלשהו של מספרים ומחזירה את הממוצע שלהם.

average(10, 20, 30);    // 20
average(5, 10);          // 7.5
average(100);            // 100
average();               // 0

ב. כתבו פונקציה joinWith שמקבלת separator כפרמטר ראשון ומחרוזות כ-rest parameters, ומחזירה אותן מחוברות עם ה-separator.

joinWith("-", "a", "b", "c");     // "a-b-c"
joinWith(" ", "Hello", "World");  // "Hello World"
joinWith(", ", "one", "two", "three"); // "one, two, three"

תרגיל 4 - callback functions

א. כתבו פונקציה applyToEach שמקבלת מערך ופונקציית callback, ומחזירה מערך חדש שבו כל איבר עבר דרך ה-callback:

applyToEach([1, 2, 3], x => x * 2);        // [2, 4, 6]
applyToEach(["hello", "world"], s => s.toUpperCase()); // ["HELLO", "WORLD"]
applyToEach([1, 4, 9], Math.sqrt);          // [1, 2, 3]

ב. כתבו פונקציה filterArray שמקבלת מערך ופונקציית callback (שמחזירה true/false), ומחזירה מערך חדש רק עם האיברים שה-callback החזיר עליהם true:

filterArray([1, 2, 3, 4, 5, 6], x => x % 2 === 0); // [2, 4, 6]
filterArray(["hi", "hello", "hey"], s => s.length > 2); // ["hello", "hey"]

תרגיל 5 - תרגום מפייתון ל-JS

תרגמו את הקוד הבא מפייתון לג׳אווהסקריפט. השתמשו ב-arrow functions כשזה מתאים:

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

def apply_operation(a, b, operation):
    return operation(a, b)

add = lambda a, b: a + b
subtract = lambda a, b: a - b
multiply = lambda a, b: a * b

print(f"5! = {factorial(5)}")
print(f"10 + 3 = {apply_operation(10, 3, add)}")
print(f"10 - 3 = {apply_operation(10, 3, subtract)}")
print(f"10 * 3 = {apply_operation(10, 3, multiply)}")

תרגיל 6 - פונקציה שמחזירה פונקציה

כתבו פונקציה createCounter שמחזירה פונקציה. בכל פעם שקוראים לפונקציה המוחזרת, היא מחזירה מספר שגדל ב-1:

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

const anotherCounter = createCounter();
console.log(anotherCounter()); // 1 (independent counter)

רמז: הפונקציה הפנימית "זוכרת" את ה-scope של הפונקציה החיצונית (closure).

תרגיל 7 - hoisting

מה ידפיס כל חלק מהקוד הבא? ענו לפני שתריצו:

// Part A
console.log(add(2, 3));
function add(a, b) {
    return a + b;
}

// Part B
// console.log(subtract(5, 3));
const subtract = function(a, b) {
    return a - b;
};

// Part C
// console.log(multiply(4, 5));
const multiply = (a, b) => a * b;

מה יקרה אם נבטל את ההערות ב-Part B ו-Part C?

תרגיל 8 - setTimeout

כתבו תוכנית שעושה את הדברים הבאים:
1. מדפיסה "Start"
2. אחרי שניה - מדפיסה "One second later..."
3. אחרי שתי שניות - מדפיסה "Two seconds later..."
4. אחרי שלוש שניות - מדפיסה "Three seconds later..."
5. מדפיסה "End" (זה ירוץ מיד, לפני ה-timeouts!)

שאלה: למה "End" מודפס לפני ההודעות של setTimeout?

תרגיל 9 - מחשבון עם callbacks

כתבו מחשבון שמשתמש ב-callbacks:

א. צרו אובייקט calculator עם מתודות: add, subtract, multiply, divide.

ב. כתבו פונקציה calculate שמקבלת שני מספרים ופונקציית callback, ומחזירה את התוצאה. הוסיפו בדיקה שה-callback הוא באמת פונקציה.

calculate(10, 3, calculator.add);      // 13
calculate(10, 3, calculator.subtract); // 7
calculate(10, 3, calculator.multiply); // 30
calculate(10, 0, calculator.divide);   // should handle division by zero
calculate(10, 3, "not a function");    // should print error

תרגיל 10 - IIFE

א. כתבו IIFE שמדפיסה "Hello from IIFE!" מיד.

ב. כתבו IIFE שמקבלת שם כפרמטר ומדפיסה ברכה.

ג. כתבו IIFE שמגדירה משתנה פנימי ומחזירה אובייקט עם פונקציות לגישה אליו. בדקו שהמשתנה לא נגיש מבחוץ:

const module = (function() {
    // your code here - define a private variable
    // return an object with get() and set() functions
})();

module.set(42);
console.log(module.get()); // 42
// how do you access the private variable directly? (you can't!)

שאלות

  1. מה ההבדל בין function declaration ל-function expression?
  2. מתי כדאי להשתמש ב-arrow function ומתי לא?
  3. מה ההבדל בין ...args ב-JS ל-*args בפייתון?
  4. מה זה callback? תנו דוגמה מהחיים.
  5. פונקציה בלי return - מה היא מחזירה ב-JS? מה בפייתון?
  6. מה זה IIFE ולמה זה שימושי?