iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
JavaScript

入門JavaScript系列 第 18

函式

  • 分享至 

  • xImage
  •  

JavaScript 中的函式是核心概念,隨著使用深入,函式有很多進階技巧和特性可以應用,讓程式碼更具彈性和功能性。

1. 匿名函式與箭頭函式

匿名函式(Anonymous Function)沒有名稱,通常用於回呼(callback)或立即執行的情況。箭頭函式(Arrow Function)是匿名函式的簡化寫法,並且有特別的 this 綁定行為。

匿名函式:

const greet = function(name) {
  return `Hello, ${name}`;
};
console.log(greet("Alice")); // Hello, Alice

箭頭函式:

const greet = (name) => `Hello, ${name}`;
console.log(greet("Alice")); // Hello, Alice

箭頭函式的 this

箭頭函式的 this 綁定於其定義時的上下文,這使得它在物件方法或回呼函式中非常實用。

const person = {
  name: "Alice",
  greet: function() {
    setTimeout(() => {
      console.log(`Hello, ${this.name}`); // 'this' 指向 person
    }, 1000);
  }
};
person.greet(); // Hello, Alice

2. 高階函式(Higher-Order Functions)

高階函式是接受另一個函式作為參數,或返回一個函式的函式。這使得它可以用來創建更動態、可重用的程式。

範例:接受函式作為參數

function applyOperation(a, b, operation) {
  return operation(a, b);
}

const sum = (x, y) => x + y;
const result = applyOperation(5, 3, sum);
console.log(result); // 8

範例:返回函式

function multiplier(factor) {
  return function(number) {
    return number * factor;
  };
}

const double = multiplier(2);
console.log(double(5)); // 10

3. 函式柯里化(Currying)

函式柯里化是將多個參數的函式轉換為嵌套的單參數函式,這使得部分應用(partial application)變得更加靈活。

範例:

function add(a) {
  return function(b) {
    return a + b;
  };
}

const addFive = add(5);
console.log(addFive(3)); // 8

簡化版本(箭頭函式實現):

const add = a => b => a + b;
console.log(add(5)(3)); // 8

4. 立即執行函式(IIFE)

立即執行函式是定義後立即執行的函式,常用來創建私有作用域,避免變數污染全局命名空間。

範例:

(function() {
  const secret = "I am private";
  console.log(secret); // I am private
})();
// console.log(secret); // 錯誤:secret 未定義

5. 函式的預設參數(Default Parameters)

當函式參數沒有被傳入值時,可以給它一個預設值。這在定義函式時,可以提高函式的靈活性。

範例:

function greet(name = "Guest") {
  return `Hello, ${name}`;
}

console.log(greet()); // Hello, Guest
console.log(greet("Alice")); // Hello, Alice

6. Rest 參數與展開運算子(Rest & Spread Operator)

rest 參數允許你將不確定數量的參數收集成一個陣列,這在處理可變參數數量時非常有用。而展開運算子可以展開陣列或物件。

Rest 參數:

function sum(...numbers) {
  return numbers.reduce((acc, num) => acc + num, 0);
}

console.log(sum(1, 2, 3, 4)); // 10

展開運算子:

const arr1 = [1, 2, 3];
const arr2 = [4, 5];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5]

const person = { name: "Alice", age: 25 };
const updatedPerson = { ...person, age: 26 }; // { name: "Alice", age: 26 }

7. 函式記憶化(Memoization)

記憶化是指將函式的計算結果緩存起來,當再次使用相同參數時,直接返回緩存的結果,這可以用來優化性能,尤其是處理重複計算時。

範例:

function memoize(fn) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache[key]) {
      return cache[key];
    }
    const result = fn(...args);
    cache[key] = result;
    return result;
  };
}

const slowFunction = num => {
  console.log("Calculating...");
  return num * 2;
};

const memoizedFunction = memoize(slowFunction);

console.log(memoizedFunction(5)); // Calculating... 10
console.log(memoizedFunction(5)); // 10 (這次不會計算,直接從緩存中取得結果)

8. 遞迴函式(Recursion)

遞迴函式是一種自我呼叫的函式,適合用來解決如樹結構、階乘、斐波那契數列等問題。

範例:階乘

function factorial(n) {
  if (n === 1) return 1;
  return n * factorial(n - 1);
}

console.log(factorial(5)); // 120

9. 函式組合(Function Composition)

函式組合是將多個函式串連起來,將一個函式的輸出作為下一個函式的輸入,這有助於簡化多步驟的邏輯處理。

範例:

const compose = (f, g) => x => f(g(x));

const addFive = x => x + 5;
const double = x => x * 2;

const addFiveAndDouble = compose(double, addFive);
console.log(addFiveAndDouble(10)); // (10 + 5) * 2 = 30

10. thiscallapplybind

在 JavaScript 中,this 是動態的,會根據函式的呼叫方式來決定它指向的對象。透過 callapplybind,我們可以手動指定 this

callapply

這兩個方法都用來立即執行函式並明確設定 this,但 call 是逐一傳遞參數,apply 是用陣列傳遞參數。

function greet(greeting, punctuation) {
  console.log(`${greeting}, ${this.name}${punctuation}`);
}

const person = { name: "Alice" };

greet.call(person, "Hello", "!"); // Hello, Alice!
greet.apply(person, ["Hi", "?"]); // Hi, Alice?

bind

bind 不會立即執行函式,而是返回一個綁定了 this 的新函式。

const person = { name: "Alice" };

const greetPerson = greet.bind(person);
greetPerson("Hello", "!"); // Hello, Alice!

總結

這些進階的 JavaScript 函式技巧能夠大幅提升程式的彈性與可維護性。從高階函式、柯里化到記憶化和遞迴,掌握這些技術可以在寫複雜應用時更加得心應手。


上一篇
迴圈應用
下一篇
函式應用
系列文
入門JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言