ปิดใน JavaScript

Mar 18 2023
Closure คืออะไร และเราจะใช้มันได้เมื่อไหร่? เพื่อให้เข้าใจถึงการปิด เราจำเป็นต้องรู้เกี่ยวกับ 2 แนวคิดง่ายๆ ใน JavaScript: ฟังก์ชันที่ซ้อนกันและการส่งคืนฟังก์ชัน Nested Functions ใน JavaScript เราสามารถมีฟังก์ชันซ้อนกันได้

Closure คืออะไร และเราจะใช้มันได้เมื่อไหร่?

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

ฟังก์ชันที่ซ้อนกัน

ใน JavaScript เราสามารถมีฟังก์ชันซ้อนกันได้ ฟังก์ชันภายในสามารถเข้าถึงตัวแปรและพารามิเตอร์ของฟังก์ชันภายนอกได้

ลองตรวจสอบตัวอย่างต่อไปนี้:

function greetPerson(name) {
  const message = 'Hello';
  
  function displayMessage() {
    console.log(`${message} ${name}!`);
  }

  displayMessage();
}

greetPerson('Alex'); // Hello Alex!

การคืนฟังก์ชัน

นอกจากการประกาศและเรียกใช้ฟังก์ชันภายในภายในฟังก์ชันภายนอกแล้ว เรายังสามารถส่งคืนฟังก์ชันภายในเพื่อให้สามารถเรียกใช้จากภายนอกได้

ลองดูตัวอย่างนี้:

function greetPerson(name) {
  const message = 'Hello';
  
  function displayMessage() {
    console.log(`${message} ${name}!`);
  }

  return displayMessage;
}

const displayMessageFunction = greetPerson('Alex');

console.log(typeof(displayMessageFunction)); // function
displayMessageFunction(); // Hello Alex!

ปิด

หลังจากที่เราเข้าใจ 2 แนวคิดนี้แล้ว "คำจำกัดความ" ของการปิดก็ค่อนข้างง่าย

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

มาดูตัวอย่างอื่นที่เราจะเห็นว่าสามารถใช้การปิดได้อย่างไร:

function counterFunction() {
 let counter = 0;

 function increaseCounter() {
  return counter += 1;
 }

 return increaseCounter;
}

// counter reffers to the increaseCounter returned by the counterFunction
const counter = counterFunction();

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
console.log(counter()); // 4

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

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

ควรใช้การปิดเมื่อใด

เราสามารถใช้การปิดเพื่อให้เกิดการห่อหุ้มใน JavaScript ซึ่งสามารถทำได้โดยการซ่อนรายละเอียดการใช้งาน ด้วยวิธีนี้ เราสามารถสร้างตัวแปรและฟังก์ชันส่วนตัวได้

ลองตรวจสอบตัวอย่างต่อไปนี้ ซึ่งเราต้องการสรุปข้อมูลบางส่วนโดยใช้ฟังก์ชันและวัตถุเท่านั้น:

const counter = (function () {
  let privateCounter = 0;

  function changeBy(val) {
    privateCounter += val;
  }

  function increaseCounter() {
    changeBy(1);
  }

  function decreaseCounter() {
    changeBy(-1);
  }

  function decreaseCounter() {
    return privateCounter;
  }

  return { increaseCounter, decreaseCounter, getCounterValue };
})();

console.log(counter.getCounterValue()); // 0

counter.increaseCounter();
counter.increaseCounter();

console.log(counter.getCounterValue()); // 2

counter.decreaseCounter();

console.log(counter.getCounterValue()); // 1

เราสามารถควบคุมค่าของตัวนับจากภายนอกได้โดยการเรียกincreaseCounterและdecreaseCounterและเราสามารถรับค่าได้โดยการเรียกgetCounterValueฟังก์ชันซึ่งทำงานเหมือนตัวรับ

ด้วยวิธีนี้ เราสามารถจำลองpublicและprivateเข้าถึงตัวระบุและบรรลุการห่อหุ้ม

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

นั่นคือทั้งหมด!

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