Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

Undeclared vs Undefined ใน JavaScript - ความแตกต่างสำคัญ

หลายคนสับสนระหว่าง Undeclared (ไม่ได้ประกาศ) และ Undefined (ประกาศแต่ไม่มีค่า) ทั้งคู่เกี่ยวกับตัวแปรที่ "ไม่มีค่า" แต่ความหมายและพฤติกรรมต่างกันหมด

ความแตกต่างพื้นฐาน

ลักษณะUndeclared (ไม่ได้ประกาศ)Undefined (ไม่มีค่า)
สาเหตุไม่เคยใช้ var, let, const ประกาศประกาศแล้วแต่ไม่ได้กำหนดค่า
การเข้าถึง❌ โยน ReferenceError✅ คืนค่า undefined
typeof"undefined" (ไม่โยน Error)"undefined"
Scopeกลายเป็น Global Property (ใน Non-strict)อยู่ใน Scope ที่ประกาศ
Strict Mode❌ ReferenceError เสมอ✅ ปกติ

ตัวอย่างแสดงความแตกต่าง

<!DOCTYPE html>
<html lang="th">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Undeclared vs Undefined</title>
    <style>
        body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
        .result { font-size: 18px; font-weight: 500; color: blueviolet; margin: 10px 0; padding: 10px; background: #f8f9fa; }
        button { padding: 8px 16px; margin: 10px 0; cursor: pointer; }
        .error { color: #dc3545; }
    </style>
</head>
<body>
    <h1>Undeclared vs Undefined ใน JavaScript</h1>
    <div class="result" id="undefinedResult"></div>
    <div class="result" id="undeclaredResult"></div>
    <button class="Btn" id="testBtn">ทดสอบการเข้าถึงตัวแปร</button>
    <h3>กดปุ่มเพื่อเข้าถึงตัวแปร Undefined และ Undeclared</h3>

    <script>
        const undefinedResult = document.getElementById("undefinedResult");
        const undeclaredResult = document.getElementById("undeclaredResult");
        const btn = document.getElementById("testBtn");
        
        // Declared but not assigned = undefined
        let a;
        
        btn.addEventListener("click", () => {
            // 1. เข้าถึงตัวแปร undefined
            undefinedResult.innerHTML = `เข้าถึงตัวแปร undefined (let a;) = ${a}
`; undefinedResult.innerHTML += `typeof a = "${typeof a}"`; // 2. เข้าถึงตัวแปร undeclared (b ไม่ได้ประกาศ) try { undeclaredResult.innerHTML = `เข้าถึงตัวแปร undeclared (b) = ${b}`; } catch (err) { undeclaredResult.innerHTML = `เข้าถึงตัวแปร undeclared = ${err.name}: ${err.message}
`; undeclaredResult.innerHTML += `typeof b = "${typeof b}" (typeof ไม่โยน Error)`; } }); </script> </body> </html>

ผลลัพธ์

Undefined (let a;):
เข้าถึง = undefined
typeof a = "undefined"

Undeclared (b ไม่ได้ประกาศ):
เข้าถึง = ReferenceError: b is not defined
typeof b = "undefined" (typeof ไม่โยน Error!)

รายละเอียดเพิ่มเติม

1. Undefined - ค่าที่ "ไม่มีค่า" อย่างเป็นทางการ

let x;                    // undefined
let y = undefined;        // undefined (Explicit)
let z = void 0;           // undefined (Alternative)

function foo() {}         // return undefined
foo();                    // undefined

const obj = {};
obj.missingProp;          // undefined (Property ไม่มีอยู่)

2. Undeclared - ตัวแปรที่ "ไม่มีอยู่จริง"

// Non-strict mode (Legacy)
function test() {
    undeclaredVar = 10;   // สร้าง Global Variable! (Implicit Global)
}
test();
console.log(window.undeclaredVar); // 10

// Strict Mode ("use strict")
function testStrict() {
    "use strict";
    undeclaredVar = 10;   // ❌ ReferenceError: undeclaredVar is not defined
}

3. ตรวจสอบอย่างปลอดภัย

// ✅ ปลอดภัย - ใช้ typeof (ไม่โยน Error ทั้งคู่)
if (typeof myVar === "undefined") {
    console.log("myVar เป็น undeclared หรือ undefined");
}

// ✅ ปลอดภัย - ใช้ try/catch
try {
    myVar; // ReferenceError ถ้า undeclared
} catch (e) {
    console.log("undeclared");
}

// ✅ สำหรับ Object Properties - ใช้ in operator / hasOwnProperty
if ("prop" in obj) { }           // true ถ้ามีใน Prototype Chain
if (obj.hasOwnProperty("prop")) { } // true ถ้าเป็น Own Property

Best Practices

  • ✅ ใช้ let/const เสมอ (Block Scope, TDZ ป้องกัน Undeclared Access)
  • ✅ ใช้ "use strict" หรือ ES Modules (Strict Mode โดยอัตโนมัติ)
  • ✅ เริ่มต้นค่าให้ตัวแปรเสมอ: let x = null; หรือ let x = 0;
  • ✅ ตรวจสอบด้วย typeof x === "undefined" สำหรับ Global Check
  • ❌ หลีกเลี่ยง Implicit Globals (Assignment โดยไม่มี Declaration)