ฟังก์ชัน ในภาษา JavaScript

ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับฟังก์ชันในภาษา JavaScript เราจะพูดถึงการประกาศและใช้งานฟังก์ชัน และคุณสมบัติที่สำคัญเกี่ยวกับฟังก์ชัน นี่เป็นเนื้อหาในบทนี้

  • ฟังก์ชันคืออะไร
  • การประกาศและใช้งานฟังก์ชัน
  • การส่งค่ากลับ (return)
  • Function expression
  • ฟังก์ชันพารามิเตอร์กับค่าเริ่มต้น
  • Function rest parameters
  • ตัวอย่างการใช้งานฟังก์ชัน

ฟังก์ชันคืออะไร

ฟังก์ชัน (Function) คือกลุ่มของชุดคำสั่งที่ถูกรวมเข้าด้วยกันสำหรับการทำงานบางอย่าง ฟังก์ชันสามารถรับพารามิเตอร์เพื่อนำมาทำงานและส่งค่ากลับได้ นอกจากนี้การสร้างฟังก์ชันทำให้เราสามารถเรียกใช้มันซ้ำๆ ซึ่งเป็นการนำโค้ดกลับมาใช้ใหม่ได้ (Reusable) ซึ่งนี่เป็นแนวคิดพื้นฐานของการใช้งานฟังก์ชันในการเขียนโปรแกรม

ก่อนที่จะใช้งานฟังก์ชัน มันจะต้องถูกประกาศหรือสร้างขึ้นมาก่อน นี่เป็นรูปแบบของการประกาศฟังก์ชันในภาษา JavaScript

function name(param1, param2, ...) {
    // Statements
    return value; // Optional
}

การประกาศฟังก์ชันจะใช้คำสั่ง function ตามด้วยชื่อของฟังก์ชัน name การตั้งชื่อของฟังก์ชันนั้นจะเหมือนกับตัวแปร สามารถประกอบไปด้วยตัวอักษร ตัวเลข และสัญลักษณ์ Underscore (_) ในกรณีที่ชื่อของฟังก์ชันมีหลายคำมักจะกำหนดในรูปแบบ camelCase

ในวงเล็บหลังจากชื่อฟังก์ชันเป็นการกำหนดพารามิเตอร์ มันใช้สำหรับรับค่าในตอนที่ฟังก์ชันถูกเรียกใช้งาน พารามิเตอร์นั้นเป็นตัวแปรที่มีขอบเขตอยู่ภายในฟังก์ชัน และในกรณีที่ฟังก์ชันไม่มีพารามิเตอร์ วงเล็บจะถูกว่างเปล่าเอาไว้

ฟังก์ชันสามารถส่งค่ากลับไปยังที่ที่มันถูกเรียกใช้ได้ โดยการใช้คำสั่ง return และตามด้วยค่าที่ต้องการส่งกลับ ถ้าหากเราละเว้นการส่งค่ากลับ undefined จะเป็นค่าที่ส่งกลับไปแทน

การประกาศและใช้งานฟังก์ชัน

หลังจากคุณได้ทราบวิธีการประกาศฟังก์ชันแล้ว ต่อไปมาเริ่มประกาศฟังก์ชันในภาษา JavaScript เพื่อใช้งานกัน นี่เป็นตัวอย่าง

function currentDate() {
    let date = new Date().toDateString();
    console.log("The current date is: " + date);
}

function sayHi(name) {
    console.log("Hi " + name);
}

currentDate();
sayHi("Metin");
sayHi("JavaScript");

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

The current date is: Tue Aug 11 2020
Hi Metin
Hi JavaScript

เราได้ประกาศฟังก์ชันมาสองฟังก์ชันสำหรับการทำงานที่แตกต่างกัน ฟังก์ชัน currentDate ใช้สำหรับแสดงวันที่ปัจจุบันออกทางหน้าจอ ในขณะที่ฟังก์ชัน sayHi แสดงคำกล่าวทักทายจากชื่อที่ส่งเข้าไปยังฟังก์ชัน

currentDate();
sayHi("Metin");
sayHi("JavaScript");

จากนั้นเป็นการเรียกใช้งานฟังก์ชันด้วยชื่อของมัน ฟังก์ชัน currentDate เป็นฟังก์ชันที่ไม่มีพารามิเตอร์ ดังนั้นตอนเรียกใช้ไม่ต้องส่งอาร์กิวเมนต์เข้าไปยังฟังก์ชัน ส่วนฟังก์ชัน sayHi มีหนึ่งพารามิเตอร์คือ name ดังนั้นในตอนเรียกใช้ต้องส่งอาร์กิวเมนต์สำหรับพารามิเตอร์ดังกล่าวด้วย ในกรณีนี้ "Metin" และ "JavaScript" คืออาร์กิวเมนต์ที่ส่งไปยังพารามิเตอร์ของฟังก์ชัน

สังเกตว่าเราเรียกใช้งานฟังก์ชัน sayHi ถึงสองครั้งและนี่คือข้อดีของฟังก์ชัน เราสามารถเรียกใช้งานฟังก์ชันกี่ครั้งก็ได้หลังจากที่มันถูกประกาศไปแล้ว

ในบทนี้คุณอาจจะเห็นเราใช้คำว่า พารามิเตอร์ (Parameter) และ อาร์กิวเมนต์ (Argument) ควบคู่กัน พารามิเตอร์นั้นเป็นตัวแปรที่ประกาศเพื่อรับค่าในฟังก์ชัน ในขณะที่อาร์กิวเมนต์เป็นค่าที่ส่งในตอนเรียกใช้ฟังก์ชันไปยังพารามิเตอร์ของฟังก์ชัน ซึ่งจะสอดคล้องกันดังต่อไปนี้

// Function definition
function fnName(param1, param2, ...) {
    // Do something
}

// Calling function
fnName(arg1, arg2, ...);

จะกล่าวได้ว่าฟังก์ชันพารามิเตอร์และอาร์กิวเมนต์นั้นเป็นค่าหรือสิ่งเดียวกัน แต่มันเพียงเกิดขึ้นคนละที่ในโปรแกรม และเมื่อเรียกใช้ฟังก์ชันจำนวนอาร์กิวเมนต์ที่ส่งควรจะเท่ากับจำนวนของพารามิเตอร์ที่ฟังก์ชันมีเสมอ

การส่งค่ากลับ (return)

ในตัวอย่างก่อนหน้า เรายังไม่ได้ส่งค่าใดๆ กลับมาจากฟังก์ชัน เราสามารถส่งค่ากลับจากฟังก์ชันโดยการใช้คำสั่ง return ต่อไปเป็นตัวอย่างของฟังก์ชันสำหรับหาผลรวมของตัวเลขสองตัว และส่งผลลัพธ์ที่ได้กลับมา นี่เป็นตัวอย่าง

sum.js
function sum(a, b) {
    return a + b;
}

console.log("4 + 5 = " + sum(4, 5));
console.log("1 + -3 = " + sum(1, -3));

let doubleSum = sum(5, 5) * 2;
console.log("(5 + 5) * 2 = " + doubleSum);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

4 + 5 = 9
1 + -3 = -2
(5 + 5) * 2 = 20

ในตัวอย่าง เป็นการประกาศและใช้งานฟังก์ชันสำหรับหาผลรวมของตัวเลขสองตัว ฟังก์ชัน sum มีสองพารามิเตอร์คือ a และ b ซึ่งเป็นตัวเลขที่ต้องการส่งเข้ามาหาผลรวมภายในฟังก์ชัน และฟังก์ชันส่งค่ากลับเป็นผลรวมของตัวเลขทั้งสองด้วยคำสั่ง return

ในการทำงานของฟังก์ชันนั้น คำสั่ง return เป็นการสั่งให้ฟังก์ชันจบการทำงานและส่งค่ากลับไปยังจุดที่เรียกใช้งานฟังก์ชัน เราสามารถใช้มันเพื่อจบการทำงานและข้ามการทำงานในคำสั่งที่เหลือของฟังก์ชันได้ มาดูตัวอย่างของฟังก์ชันสำหรับหาค่า Factorial ของตัวเลข และการใช้งานคำสั่ง return ในฟังก์ชัน

factorial.js
function factorial(n) {
    if (n == 0) {
        return 1;
    }
    let fac = 1;
    for (let i = 1; i <= n; i++) {
        fac *= i;
    }
    return fac;
}

console.log("0! = " + factorial(0));
console.log("3! = " + factorial(3));
console.log("5! = " + factorial(5));

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

0! = 1
3! = 6
5! = 120

ฟังก์ชัน factorial นั้นใช้สำหรับหาค่า Factorial โดยรับพารามิเตอร์เป็นตัวเลขจำนวนเต็ม n ที่ส่งเข้ามายังฟังก์ชันเพื่อนำมาคำนวณ

if (n == 0) {
    return 1;
}

ในฟังก์ชันเราได้ตรวจสอบเงื่อนไขว่าถ้าค่าในตัวแปร n ที่ส่งเข้ามามีค่าเท่ากับ 0 เราใช้คำสั่ง return ส่งค่ากลับเป็น 1 ในทันที นั่นทำให้ฟังก์ชันจบการทำงานและไม่ทำสั่งอื่นๆ ต่อ และในกรณีที่ค่าในตัวแปร n ไม่เท่ากับ 0 ฟังก์ชันทำงานปกติจนมันพบกับคำสั่ง return fac ด้านล่างเพื่อจบการทำงาน

ฟังก์ชันนั้นสามารถส่งค่ากลับซึ่งไม่ได้จำกัดเพียงประเภทข้อมูลพื้นฐาน แต่เป็นข้อมูลประเภทใดๆ ในภาษา JavaScript ยกตัวอย่างเช่น

function getUser() {
    return {
        id: 1,
        name: "Metin"
    };
};

function getFunction() {
    return function () {
        console.log("I'm a function");
    };
}

ฟังก์ชัน getUser ส่งค่ากลับเป็น Object literal ที่ประกอบไปด้วย Property name และ id ส่วนฟันก์ชัน getFunction นั้นเป็นฟังก์ชันที่ส่งค่ากลับเป็นฟังก์ชัน ซึ่งเราเรียกฟังก์ชันประเภทนี้ว่า Closure

Function expression

Function expression คือรูปแบบการประกาศฟังก์ชันซึ่งฟังก์ชันจะถูกสร้างขึ้นในขณะที่โปรแกรมทำงาน ในภาษา JavaScript ฟังก์ชันนั้นถือว่าเป็นค่าๆ หนึ่งที่มีประเภทข้อมูลเป็น function และสามารถกำหนดเป็นค่าของตัวแปรเหมือนกับออบเจ็คประเภทอื่นๆ ได้ นี่เป็นตัวอย่างของการประกาศ Function expression ในภาษา JavaScript

let sayHi = function (name) {
    console.log("Hi " + name);
};

let sum = function (a, b) {
    return a + b;
};

sayHi("Metin");
console.log(sum(2, 3));

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Hi Metin
5

เราได้ประกาศสองฟังก์ชัน Function expression และกำหนดค่ามันให้กับตัวแปร sayHi และ sum ตามลำดับ เมื่อเรากำหนดค่าเป็นฟังก์ชันให้กับตัวแปร นั่นจะทำให้เราสามารถใช้ตัวแปรเหมือนกับว่ามันเป็นฟังก์ชันได้

สิ่งที่แตกต่างระหว่าง Function expression และฟังก์ชันปกติก็คือ Function expression นั้นจะถูกสร้างในตอนที่โปรแกรมทำงาน ในขณะที่ฟังก์ชันปกติจะถูกสร้างในตอนที่โปรแกรมคอมไพล์ ยกตัวอย่างเช่น

sayHi("Metin");     // Hi Metin

function sayHi(name) {
    console.log("Hi " + name);
}

ในตัวอย่างเป็นการประกาศฟังก์ชัน sayHi ในรูปแบบปกติ และโปรแกรมนี้จะสามารถทำงานได้เมื่อโปรแกรมรัน เพราะว่าฟังก์ชันในภาษา JavaScript นั้นถูกสร้างในตอนที่โปรแกรมคอมไพล์ นั่นหมายความว่าในตอนที่เราเรียกใช้ฟังก์ชัน sayHi ในบรรทัดแรก ฟังก์ชันได้ถูกสร้างมาก่อนแล้ว

ตอนนี้ลองมาเปลี่ยนเป็นประกาศฟังก์ชันในรูปแบบของ Function expression แทน

sayHi("Metin"); // Error

let sayHi = function (name) {
    console.log("Hi " + name);
};

// Call here will work

เมื่อเรารันโปรแกรมนี้จะเกิดข้อผิดพลาดขึ้น เนื่องจากในบรรทัดที่เราเรียกใช้งาน sayHi มันยังไม่ได้ถูกสร้างขึ้น ซึ่งนี่เป็นข้อผิดพลาดทั่วไปเหมือนกับการใช้งานตัวแปรที่ไม่มีอยู่ และเพื่อใช้งานฟังก์ชัน sayHi เราต้องใช้หลังจากที่มันได้ประกาศไปแล้วนั่นเอง

ฟังก์ชันพารามิเตอร์กับค่าเริ่มต้น

ฟังก์ชันในภาษา JavaScript นั้นสามารถที่จะกำหนดค่าเริ่มต้นให้กับพารามิเตอร์ของฟังก์ชันได้ เมื่อพารามิเตอร์มีค่าเริ่มต้น เราสามารถที่จะส่งหรือไม่ส่งค่าสำหรับพารามิเตอร์นั้นมาก็ได้ และถ้าหากไม่ส่งค่าเริ่มต้นจะถูกใช้งานแทน

จากตัวอย่างก่อนหน้า เราจะเขียนฟังก์ชัน sayHi ใหม่และกำหนดค่าเริ่มต้นให้กับพารามิเตอร์ name นี่เป็นตัวอย่าง

default_parameter.js
function sayHi(name = "Guest") {
    console.log("Hi " + name);
}

sayHi();
sayHi("Metin");

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Hi Guest
Hi Metin

ในตัวอย่าง เรากำหนดค่าเริ่มต้นให้กับพารามิเตอร์ name เป็น "Guest" เมื่อพารามิเตอร์ของฟังก์ชันมีการกำหนดค่าเริ่มต้น เราสามารถเรียกใช้งานฟังก์ชันโดยไม่ส่งค่ามาได้ ซึ่งค่าเริ่มต้นจะถูกใช้แทน

sayHi("Metin");

และเช่นเดิมเรายังสามารถเรียกใช้งานโดยการส่งค่าพารามิเตอร์ในรูปแบบปกติได้ การกำหนดค่าเริ่มต้นให้กับฟังก์ชันนั้นอำนวยความสะดวกเป็นอย่างมากในการเขียนโปรแกรม และฟังก์ชันเป็นจำนวนมากในภาษา JavaScript นั้นมีค่าเริ่มต้นให้กับพารามิเตอร์

ถ้าหากฟังก์ชันนั้นมีหลายพารามิเตอร์และเราต้องการกำหนดค่าเริ่มต้นให้กับพารามิเตอร์เหล่านั้น ค่าเริ่มต้นจะต้องถูกกำหนดมาจากพารามิเตอร์ที่อยู่ทางด้านขวาสุดเสมอ ยกตัวอย่างเช่น

function fn1(a, b, c = 3) {
    // Do something
}

function fn2(a, b = 2, c = 3) {
    // Do something
}

function fn3(a = 1, b = 2, c = 3) {
    // Do something
}

ในตัวอย่าง เป็นการกำหนดค่าเริ่มต้นให้กับฟังก์ชันในกรณีที่มันมีมากกว่าหนึ่งพารามิเตอร์ โดยเราต้องกำหนดให้กับพารามิเตอร์ที่อยู่ทางด้านขวาก่อนเสมอ และในการเรียกใช้งานฟังก์ชัน จำนวนค่าที่ส่งเข้ามาต้องมีอย่างน้อยเท่ากับจำนวนของพารามิเตอร์ที่ไม่มีค่าเริ่มต้น

// Can be called as
// At least 2 parameters
fn1(1, 2);
fn1(1, 2, 3);

// At least 1 parameter
fn2(1);
fn2(1, 2);
fn2(1, 2, 3);

// Parameters are optional
fn3();
fn3(1);
fn3(1, 2);
fn3(1, 2, 3);

ในตอนเรียกใช้งานฟังก์ชันนั้นค่าอาเรย์กิวเมนต์ที่ส่งเข้ามายังฟังก์ชันจะต้องมีอย่างน้อยเท่ากับจำนวนของพารามิเตอร์ที่ไม่ได้กำหนดค่าเริ่มต้นเสมอ และเนื่องจากฟังก์ชัน fn3 มีการกำหนดค่าเริ่มต้นให้กับพารามิเตอร์ทั้งหมด ดังนั้นเราสามารถเรียกใช้งานฟังก์ชันโดยไม่ส่งอาร์กิวเมนต์มาเลยก็ได้ ซึ่งค่าเริ่มต้นทั้งหมดจะถูกใช้แทน

Function rest parameters

Rest parameter คือการกำหนดพารามิเตอร์ของฟังก์ชันโดยที่เราสามารถเรียกใช้งานฟังก์ชันโดยส่งอาร์กิวเมนต์มาเป็นจำนวนเท่าไหร่ก็ได้ โดยที่ Rest parameter จะเก็บรวบรวมเอาไว้ในตัวแปรอาเรย์เพื่อใช้งานในฟังก์ชัน ก่อนเริ่มมาดูตัวอย่างของฟังก์ชัน sum สำหรับรวมตัวเลขสองตัวเข้าด้วยกันในตัวอย่างที่แล้ว

function sum(a, b) {
    return a + b;
}

และอย่างที่คุณเห็น ฟังก์ชันนี้ทำงานกับแค่สองพารามิเตอร์เท่านั้น แล้วถ้าหากเราต้องการให้ฟังก์ชันสามารถบวกตัวเลขสามตัวหรือห้าตัวได้ในฟังก์ชันเดียว เราจะทำแบบนั้นได้อย่างไร คำตอบก็คือการกำหนด Rest parameter ให้กับฟังก์ชันดังตัวอย่างต่อไปนี้

rest_parameter.js
function sum(...numbers) {
    let s = 0;
    for (let n of numbers) {
        s += n;
    }
    return s;
}

console.log(sum(3, 5));
console.log(sum(3, 5, 2));
console.log(sum(3, 5, 2, 16, 19));

นี่เป็นผลลัพธ์การทำงานของโปรแกรม ตอนนี้ฟังก์ชัน sum ของเราสามารถรองรับการส่งอาร์กิวเมนต์เป็นจำนวนเท่าไหร่ก็ได้

8
10
45

เพื่อกำหนดพารามิเตอร์ให้เป็น Rest parameter ใส่เครื่องหมาย ... หน้าชื่อของพารามิเตอร์ นั่นจะทำให้ค่าทั้งหมดที่ส่งเข้ามาถูกรวบรวมเป็นอาเรย์และเก็บไว้ในตัวแปร numbers และเราสามารถใช้มันเหมือนอาเรย์ปกติทั่วไป

นอกจากนี้ Rest parameter ยังสามารถใช้ร่วมกับพารามิเตอร์แบบปกติได้ ในกรณีนี้ เราต้องกำหนด Rest parameter ที่ด้านหลังสุดเสมอ ยกตัวอย่างเช่น

function myFunction(first, ...rest) {
    console.log("first: " + first);
    console.log("rest: " + rest);
}

myFunction(1, 2, 3, 4, 5);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

first: 1
rest: 2,3,4,5

เมื่อเราเรียกใช้งานฟังก์ชัน พารามิเตอร์แรกจะเก็บในตัวแปร first และพารามิเตอร์ที่เหลือจะถูกรวบรวมเป็นอาเรย์และเก็บในตัวแปร rest

ตัวอย่างการใช้งานฟังก์ชัน

ในตัวอย่างก่อนหน้า คุณอาจจะเห็นว่าโค้ดภายในฟังก์ชันของเรานั้นมีไม่มากแล้วทำไมเราถึงต้องสร้างมันเป็นฟังก์ชัน คำตอบก็คือเพื่อทำให้มันนำกลับมาใช้ซ้ำได้ และมันช่วยเราให้สามารถแยกโค้ดส่วนต่างๆ ออกจากกันได้ นี่เป็นตัวอย่างโปรแกรมสำหรับค้นหาจำนวนเฉพาะระหว่าง 1 - 100 ในภาษา JavaScript

prime_numbers.js
// Function declaration
function isPrime(n) {
    if (n == 1) {
        return false;
    }
    for (let i = 2; i <= n; i++) {
        if (n % i == 0 && n != i) {
            return false;
        }
    }
    return true;
}

// Main program
let primeNumbers = [];
for (let i = 1; i <= 100; i++) {
    if (isPrime(i)) {
        primeNumbers.push(i);
    }
}

console.log("Prime numbers from 1 to 100:");
console.log(primeNumbers.join(", "));
console.log(primeNumbers.length + " numbers in total");

นี่เป็นผลลัพธ์การทำงานของโปรแกรม จำนวนเฉพาะที่มีค่าอยู่ระหว่าง 1 - 100 นั้นมีจำนวน 25 ตัว

Prime numbers from 1 to 100:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
25 numbers in total

เราได้สร้างฟังก์ชัน isPrime สำหรับตรวจสอบว่าตัวเลขเป็นจำนวนเฉพาะหรือไม่ ฟังก์ชันรับพารามิเตอร์เป็นตัวเลขจำนวนเต็มและส่งค่ากลับเป็น Boolean เพื่อบอกว่าตัวเลขเป็นจำนวนเฉพาะหรือไม่ เราได้แยกส่วนการตรวจสอบจำเป็นเฉพาะออกไปเป็นฟังก์ชัน

for (let i = 1; i <= 100; i++) {
    if (isPrime(i)) {
        primeNumbers.push(i);
    }
}

และในส่วนของโปรแกรมหลักนั้นจะทำแค่วนตัวเลขจาก 1 - 100 และเรียกใช้งานฟังก์ชัน isPrime ในตอนนี้ โค้ดส่วนของการตรวจสอบจำนวนเฉพาะถูกแบ่งแยกออกไป และมันทำให้โค้ดอ่านเข้าใจได้ง่ายขึ้น เนื่องจากชื่อของฟังก์ชันมีความหมายในตัวมันเอง และเราไม่จำเป็นต้องเขียนโค้ดจำนวนมากไว้ในคำสั่ง for loop

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับพื้นฐานของฟังก์ชันในภาษา JavaScript ซึ่งเป็นสิ่งที่สำคัญในการทำความเข้าใจกับฟังก์ชันในขั้นสูงต่อไป ในภาษา JavaScript ฟังก์ชันมีเนื้อหาที่มากและค่อนข้างซับซ้อนและเราจะไม่ครอบคลุมมันในบทนี้

และนี่เป็นเนื้อหาเพิ่มเติ่มเกี่ยวกับฟังก์ชันในภาษา JavaScript ถ้าหากคุณต้องการ มันเป็นเรื่องดีถ้าหากคุณได้เรียนรู้เกี่ยวกับมันแต่ไม่ได้บังคับ