ขอบเขตตัวแปรส่วนกลางและเฉพาะรายการ

ในบทความนี้ คุณจะได้เรียนรู้เกี่ยวกับขอบเขตและวิธีการทำงานของขอบเขตใน JavaScript

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

ขอบเขตช่วยคุณในเรื่องต่อไปนี้ได้

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

ขอบเขตคืออะไร

ขอบเขตของตัวแปรจะกำหนดตำแหน่งที่ใช้ตัวแปรภายในโค้ดได้

JavaScript กำหนดตัวแปรของขอบเขตรวมหรือภายในเครื่อง:

  • ตัวแปรที่มีขอบเขตรวมจะใช้ได้จากขอบเขตอื่นๆ ทั้งหมดภายในโค้ด JavaScript
  • ตัวแปรที่มีขอบเขตภายในใช้ได้เฉพาะในบริบทเฉพาะรายการและสร้างขึ้นโดยคีย์เวิร์ด เช่น var, let และ const หากคุณใช้คีย์เวิร์ด var, let หรือ const เพื่อสร้างตัวแปรภายในฟังก์ชัน ตัวแปรนั้นจะมีขอบเขตภายในเครื่อง

ส่วนต่อไปในบทความนี้จะกล่าวถึงขอบเขตการบล็อกและคำศัพท์

  • ตัวแปรขอบเขตการบล็อกจะพร้อมใช้งานภายในการบล็อกตามที่กำหนดโดยตำแหน่งของวงเล็บปีกกาซึ่งกำหนดคำสั่งบล็อกไว้ เฉพาะตัวแปรที่ประกาศด้วยคีย์เวิร์ด let หรือ const เท่านั้นที่มีขอบเขตการบล็อก
  • ขอบเขตพิเศษใช้ตําแหน่งที่มีการประกาศตัวแปรในซอร์สโค้ดเพื่อระบุตําแหน่งที่ตัวแปรนั้นจะใช้ได้ คุณใช้การปิดเพื่อให้สิทธิ์ฟังก์ชันแบบปิดในการเข้าถึงตัวแปรที่อ้างอิงในขอบเขตภายนอกที่เรียกว่าสภาพแวดล้อมคำศัพท์

เมื่อมีการเข้าถึงตัวแปรภายในขอบเขต JavaScript จะส่งกลับค่าที่กำหนดไว้หรือทำให้เกิดข้อผิดพลาด

วิธีประกาศตัวแปร

  • ใช้คีย์เวิร์ด var, const หรือ let เพื่อประกาศตัวแปรขอบเขตระดับท้องถิ่นหรือส่วนกลาง
  • ใช้คีย์เวิร์ด const หรือ let เพื่อประกาศตัวแปรขอบเขตการบล็อก

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

ตัวอย่างขอบเขต

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

const greeting = 'hello';
console.log(greeting); // 'hello'

ในตัวอย่างขอบเขตรวม ตัวแปร greeting จะได้รับการกำหนดค่า hello

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

function greet() {
  let greeting = 'Hello World!';
  console.log(greeting);
}

ตัวอย่างนี้แสดงขอบเขตการบล็อกเนื่องจากประกาศตัวแปร greeting ภายในบล็อก จึงทำให้เข้าถึงตัวแปรได้ภายในวงเล็บปีกกาเท่านั้น

if (true) {
   const greeting = 'hello';
}

console.log(greeting); // ReferenceError: greeting is not defined

โปรดสังเกตว่าเมื่อฟังก์ชัน console.log พยายามแสดงค่าของตัวแปร greeting JavaScript จะส่งข้อความแสดงข้อผิดพลาด ReferenceError แทนข้อความ hello ที่คาดไว้ เหตุผล

ระบบแสดงผลข้อผิดพลาดเนื่องจากตัวแปร greeting มีขอบเขตการบล็อก และบล็อกที่ใกล้ที่สุดเป็นส่วนหนึ่งของคำสั่งแบบมีเงื่อนไข if คุณไม่สามารถเข้าถึงตัวแปร let และ const ที่ประกาศภายในบล็อกจากภายนอกการบล็อกได้ คุณจึงเข้าถึงได้เฉพาะตัวแปร greeting ภายในวงเล็บปีกกาซึ่งระบุขอบเขตการบล็อก

ตัวอย่างนี้แก้ไขข้อผิดพลาดเนื่องจากย้ายเมธอด console.log(message) ภายในวงเล็บปีกกา โค้ดที่อัปเดตจะย้ายเมธอด console.log(message) ภายในบล็อก

if (true) {
   const greeting = 'hello';
   console.log(greeting);
}

ประเภทขอบเขต

ขอบเขตรวมทั้งหมด

คุณสามารถเข้าถึงตัวแปรด้วยขอบเขตรวมได้จากทุกที่ในโปรแกรม

ลองพิจารณาไฟล์ HTML ที่นำเข้าไฟล์ JavaScript 2 ไฟล์: file-1.js และ file-2.js:

<script src="file-1.js"></script>
<script src="file-2.js"></script>

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

คุณดูเนื้อหาของไฟล์ file-1.js และ file-2.js ได้ในข้อมูลโค้ดนี้ โปรดสังเกตความพร้อมใช้งานของตัวแปร globalMessage ในทั้ง 2 ไฟล์

// file-1.js
function hello() {
    var localMessage = 'Hello!';
}

var globalMessage = 'Hey there!';

// file-2.js
console.log(localMessage); // localMessage is not defined
console.log(globalMessage); // Hey there!

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

ขอบเขตภายในและขอบเขตฟังก์ชัน

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

ตัวอย่างนี้ประกาศตัวแปร total ในฟังก์ชัน addNumbers() คุณเข้าถึงตัวแปร a, b, และ total ภายในฟังก์ชัน addNumbers() ได้เท่านั้น

function addNumbers(a, b) {
    const total = a + b;
}

addNumbers(3, 4);

คุณใช้คีย์เวิร์ด let และ const เพื่อตั้งชื่อตัวแปรได้ JavaScript จะอัปเดตตัวแปรได้เมื่อคุณใช้คีย์เวิร์ด let แต่ตัวแปรนี้จะไม่เปลี่ยนแปลงด้วยคีย์เวิร์ด const

var variable1 = 'Declared with var';
var variable1 = 'Redeclared with var';
variable1; // Redeclared with var

let variable2 = 'Declared with let. Cannot be redeclared.';
variable2 = 'let cannot be redeclared, but can be updated';
variable2; // let cannot be redeclared, but can be updated

const variable3 = 'Declared with const. Cannot be redeclared or updated';
variable3; // Declared with const. Cannot be redeclared or updated

บล็อกขอบเขต

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

ตัวอย่างเช่น ในบล็อกนี้ ขอบเขตสำหรับตัวแปร name และค่า "Elizabeth" จะอยู่ในวงเล็บปีกกา ตัวแปรภายในขอบเขตการบล็อกจะใช้ไม่ได้นอกบล็อก

{
    const name = "Elizabeth";
}

คุณจะใช้ตัวแปรที่กําหนดขอบเขตระดับการบล็อกภายในคําสั่ง if, for หรือ while ได้

จดลูป for ทั้ง 2 รอบภายในข้อมูลโค้ดนี้ ลูป for 1 รอบจะใช้คีย์เวิร์ด var เพื่อประกาศตัวแปรเริ่มต้น ซึ่งเพิ่มขึ้นผ่านตัวเลข 0, 1 และ 2 ลูป for อีกรายการใช้คีย์เวิร์ด let เพื่อประกาศตัวแปรเริ่มต้น

for (var i = 0; i < 2; i++) {
    // ...
}

console.log(i); // 2

for (let j = 0; j < 2; j++) {
    // ...
}

console.log(j); // The j variable isn't defined.

ในตัวอย่างโค้ดก่อนหน้า คุณอาจสังเกตเห็นว่าตัวแปร i ในลูป for แรกหลุดออกไปนอกลูป for และยังคงเก็บค่า 2 ไว้เนื่องจากคีย์เวิร์ด var ไม่ได้ใช้ขอบเขตการบล็อก ปัญหาได้รับการแก้ไขใน for ลูปที่ 2 ซึ่งมีขอบเขตตัวแปร j ที่ประกาศด้วยคีย์เวิร์ด let อยู่ในขอบเขตของบล็อกในการวนซ้ำ for และหายไปหลังจากที่วนซ้ำ for เสร็จสิ้นแล้ว

การใช้ชื่อตัวแปรซ้ำในขอบเขตอื่น

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

ตัวอย่างนี้แสดงให้เห็นว่าการใช้ขอบเขตช่วยให้คุณใช้ชื่อตัวแปรเดียวกันซ้ำในฟังก์ชันต่างๆ ได้อย่างไร

function listOne() {
    let listItems = 10;
    console.log(listItems); // 10
}

function listTwo() {
   let listItems = 20;
   console.log(listItems); // 20
}

listOne();
listTwo();

ตัวแปร listItems ในฟังก์ชัน listOne() และ listTwo() ได้รับการกำหนดค่าตามที่คาดหวังไว้ ดังนั้นอย่าขัดแย้งกันเอง

การปิดและขอบเขตคำศัพท์

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

ในตัวอย่างนี้ โค้ดจะสร้างการปิดด้วยสภาพแวดล้อมแบบคลังที่สร้างขึ้นเมื่อมีการเรียกใช้ฟังก์ชัน outer() ซึ่งจะปิดทับตัวแปร hello ดังนั้นจะมีการใช้ตัวแปร hello ภายในฟังก์ชัน Callback setTimeout

function outer() {
    const hello = 'world';

    setTimeout(function () {
        console.log('Within the closure!', hello)
    }, 100);
}

outer();

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

โมดูล

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

// hello.js file
function hello() {
  return 'Hello world!';
}

export { hello };

// app.js file
import { hello } from './hello.js';

console.log(hello()); // Hello world!

การสาธิตเครื่องมือแสดงข้อมูลขอบเขต

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

บทสรุป

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

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