جلسه ۹ - کار با undefined و Null

این دو مفهوم اغلب باعث سردرگمی توسعه‌دهندگان می‌شوند، اما درک تفاوت آن‌ها برای نوشتن کدهای مستحکم و قابل پیش‌بینی ضروری است.

مفاهیم کلیدی:

۱. undefined (تعریف‌نشده):

  • مقداری است که توسط جاوااسکریپت به متغیرهای تعریف‌شده اما مقداردهی‌نشده اختصاص داده می‌شود
  • نشان‌دهنده عدم وجود مقدار به صورت غیرعمدی است
// مثال‌هایی از undefined
let name;
console.log(name); // undefined
 
function greet(message) {
    console.log(message);
}
greet(); // undefined (پارامتر ارسال نشده)
 
let user = { age: 25 };
console.log(user.name); // undefined (property وجود ندارد)

۲. null (تهی):

  • مقداری است که توسط توسعه‌دهنده به صورت عمدی تنظیم می‌شود
  • نشان‌دهنده عدم وجود مقدار به صورت عمدی است
// مثال‌هایی از null
let user = null; // تعمداً مقدار تهی تنظیم شده
 
let data = "مقدار موقت";
data = null; // ریست کردن مقدار به صورت عمدی
 
let response = { data: null, error: null }; // نشان‌دهنده عدم وجود داده

۳. تفاوت‌های کلیدی:

ویژگیundefinednull
منبعسیستم (جاوااسکریپت)توسعه‌دهنده
نوع داده”undefined""object” (باگ تاریخی)
هدفعدم مقداردهیمقدار تهی عمدی
Booleanfalsyfalsy
// مقایسه عملی
let a; // undefined
let b = null; // null
 
console.log(typeof a); // "undefined"
console.log(typeof b); // "object" (باگ تاریخی!)
 
console.log(a == null); // true (تساوی loose)
console.log(a === null); // false (تساوی strict)
console.log(b == undefined); // true (تساوی loose)
console.log(b === undefined); // false (تساوی strict)

۴. عملگر Nullish Coalescing (??):

  • فقط برای null و undefined کار می‌کند
  • برخلاف || که برای همه مقادیر falsy کار می‌کند
console.log(0 || "پیش‌فرض"); // "پیش‌فرض"
console.log(0 ?? "پیش‌فرض"); // 0
 
console.log("" || "پیش‌فرض"); // "پیش‌فرض"
console.log("" ?? "پیش‌فرض"); // ""
 
console.log(null ?? "پیش‌فرض"); // "پیش‌فرض"
console.log(undefined ?? "پیش‌فرض"); // "پیش‌فرض"

۵. بهترین روش‌ها (Best Practices):

  • همیشه با === مقایسه کنید
  • از null برای نشان‌دادن عمدی عدم مقدار استفاده کنید
  • از undefined اجتناب کنید و متغیرها را مقداردهی اولیه کنید

ارزیابی بخش ۷:

سؤال ۱: پیش‌بینی خروجی خروجی هر خط از کد زیر چیست؟

let x;
let y = null;
 
console.log(x);
console.log(y);
console.log(typeof x);
console.log(typeof y);
console.log(x === y);
console.log(x == y);

سؤال ۲: تحلیل عملگرها خروجی هر عبارت زیر چیست؟

console.log(undefined ?? "پیش‌فرض");
console.log(null ?? "مقدار جایگزین");
console.log(0 ?? "پیش‌فرض");
console.log("" ?? "پیش‌فرض");
console.log(false ?? "پیش‌فرض");

سؤال ۳: نوشتن تابع اعتبارسنجی تابعی بنویسید که یک پارامتر دریافت کند و:

  • اگر پارامتر null یا undefined بود، “مقدار تهی” برگرداند
  • در غیر این صورت، خود پارامتر را برگرداند

پاسخ‌های شما:

  1. خروجی کد: undefined, null, undefined, object, false, true
  2. عملگرها: پیش‌فرض, مقدار جایگزین, 0, , false
  3. تابع: function filterNullOrUndefined(a) { return (a ?? "مقدار تهی"); }

بازخورد و تحلیل پاسخ‌های شما:

سؤال ۱: پیش‌بینی خروجی (کاملاً صحیح ✅)

let x;
let y = null;
 
console.log(x);        // ✅ undefined (صحیح)
console.log(y);        // ✅ null (صحیح)
console.log(typeof x); // ✅ undefined (صحیح)
console.log(typeof y); // ✅ object (صحیح - باگ تاریخی جاوااسکریپت)
console.log(x === y);  // ✅ false (صحیح - انواع مختلف)
console.log(x == y);   // ✅ true (صحیح - در تساوی loose برابرند)

پاسخ‌های شما کاملاً درست است! شما تفاوت‌های مهم بین undefined و null را به خوبی درک کرده‌اید.


سؤال ۲: تحلیل عملگرها (نیاز به بازبینی 🔍)

console.log(undefined ?? "پیش‌فرض");    // ✅ "پیش‌فرض" (صحیح)
console.log(null ?? "مقدار جایگزین");   // ✅ "مقدار جایگزین" (صحیح)
console.log(0 ?? "پیش‌فرض");           // ✅ 0 (صحیح)
console.log("" ?? "پیش‌فرض");          // ❌ "" (صحیح) - پاسخ شما: "" (خالی)
console.log(false ?? "پیش‌فرض");       // ✅ false (صحیح)

توضیح:

  • عملگر ?? فقط برای null و undefined عمل می‌کند
  • مقادیر 0، "" و false جزو null یا undefined نیستند، بنابراین خودشان برگردانده می‌شوند
  • پاسخ شما برای خط ۴ درست است (رشته خالی) اما در پاسخ نوشته شده فقط "" نمایش داده شده

سؤال ۳: نوشتن تابع اعتبارسنجی (کاملاً صحیح ✅)

function filterNullOrUndefined(a) {
    return (a ?? "مقدار تهی");
}
 
// تست تابع
console.log(filterNullOrUndefined(null));      // "مقدار تهی"
console.log(filterNullOrUndefined(undefined)); // "مقدار تهی"
console.log(filterNullOrUndefined(0));         // 0
console.log(filterNullOrUndefined(""));        // ""
console.log(filterNullOrUndefined("test"));    // "test"

تابع شما کاملاً درست و بهینه نوشته شده است! استفاده از عملگر ?? راه حل بسیار تمیز و مناسب برای این مسئله است.


جمع‌بندی نهایی بخش ۷:

شما مفاهیم مهم undefined و null را به طور کامل فرا گرفته‌اید:

  • ✅ درک تفاوت منبع (سیستم vs توسعه‌دهنده)
  • ✅ آگاهی از باگ تاریخی typeof null
  • ✅ تسلط بر عملگر Nullish Coalescing (??)
  • ✅ توانایی نوشتن توابع کاربردی برای مدیریت این مقادیر

نکات مهم برای توسعه‌دهنده ارشد:

  • همیشه از === برای مقایسه با null و undefined استفاده کنید
  • از عملگر ?? زمانی که فقط می‌خواهید null و undefined را فیلتر کنید
  • متغیرها را همیشه مقداردهی اولیه کنید تا از undefined غیرمنتظره جلوگیری شود
  • از null برای نشان‌دادن عمدی “عدم مقدار” استفاده کنید