برخلاف بسیاری از زبانهای دیگر، در JavaScript دو موجودیت متفاوت وجود دارد که نبودِ یک مقدار (معنادار) را نشان میدهند: null و undefined.
مقدار ابتدایی null بهعنوان یک «مقدار خالی» تعمدی برای یک متغیر به کار میرود.
در زبانهای دیگر، ممکن است ساختار مشابهی فقط برای اشیای (ناموجود) یا انواع اشارهگر به کار برود.
در JavaScript، null عموماً نمایندهی یک مقدار خالی برای هر نوعی است.
let name = null;
// name is intentionally set to "empty" because it is not
// available
میتوانید با استفاده از عملگر تساوی سختگیرانه === بررسی کنید که آیا یک متغیر null است یا نه.
هرچند null یک مقدار ابتدایی است، عملگر typeof به دلایل تاریخی بهشکل «نادرست» object را برمیگرداند.
یعنی نمیتوان آن را بهتنهایی برای بررسی اینکه آیا متغیری null است به کار برد.
let name = null;
name === null;
// => true
// Pitfall:
typeof name;
// => 'object'
متغیری که مقداری به آن اختصاص داده نشده است، از نوع
undefinedاست.۱
یعنی در حالی که null نمایندهی یک مقدار خالی است (اما همچنان یک مقدار)، undefined نمایندهی نبودِ کامل مقدار است. 🤯
undefined در موقعیتهای مختلفی ظاهر میشود.
undefined است.undefined دریافت میکنید.undefined است.undefined است، مگر اینکه آن آرگومان مقدار پیشفرض داشته باشد.let name;
console.log(name);
// => undefined
let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined
function returnNothing() {
return;
}
console.log(returnNothing());
// => undefined
میتوانید با استفاده از عملگر تساوی سختگیرانه === یا عملگر typeof بررسی کنید که آیا متغیری undefined است.
let name;
name === undefined;
// => true
typeof name === 'undefined';
// => true
توصیه نمیشود که undefined را بهصورت دستی به یک متغیر اختصاص دهید؛ در عوض همیشه از null استفاده کنید تا روشن باشد که مقدار خالی را تعمداً تعیین کردهاید.
همانطور که پیشتر اشاره شد، دسترسی به کلیدی ناموجود در یک شیء در JavaScript undefined برمیگرداند.
اما اگر بخواهید مقدار تودرتویی را بازیابی کنید و کلید والد وجود نداشته باشد، ارزیابی کلید تودرتو روی undefined انجام میشود و به TypeError: Cannot read property ... of undefined میانجامد.
از نظر تئوری، همیشه باید وجود کلید والد را بررسی کنید تا بتوانید کلید تودرتو را بازیابی کنید.
این کار اغلب با عملگر AND یعنی && انجام میشد، اما برای مقادیر عمیقاً تودرتو به عبارتهای بسیار طولانی میانجامد.
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
برای حل این مشکل، زنجیرهسازی اختیاری در سال ۲۰۲۰ به مشخصات زبان اضافه شد.
با عملگر زنجیرهسازی اختیاری ?. میتوانید مطمئن شوید که JavaScript فقط وقتی تلاش میکند به کلید تودرتو دسترسی پیدا کند که والد null یا undefined نباشد.
در غیر این صورت undefined برگردانده میشود.
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.residence;
// => undefined
obj.address.zipCode;
// => undefined
obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined
obj.residence?.street;
// => undefined
obj.residence?.street?.number;
// => undefined
موقعیتهایی وجود دارد که میخواهید در صورت null یا undefined بودن متغیر، یک مقدار پیشفرض اعمال کنید.
در گذشته این کار اغلب با عملگر سهتایی ? یا با استفاده از ارزیابی تنبل عملگر OR یعنی || انجام میشد.
این روش یک اشکال دارد: مقدار پیشفرض در همهی مواردی اعمال میشود که متغیر یک مقدار غلط است (مثلاً '' یا 0)، نه فقط وقتی null یا undefined باشد.
این کار بهراحتی میتواند به نتایج غیرمنتظرهای منجر شود.
let amount = null;
amount = amount || 1;
// => 1
amount = 0;
amount = amount || 1;
// => 1
amount = 0;
amount ? amount : 1;
// => 1
برای رفع این مشکل، عملگر ادغام پوچ ?? معرفی شد.
درست مانند زنجیرهسازی اختیاری، در سال ۲۰۲۰ به مشخصات زبان اضافه شد.
عملگر ادغام پوچ ?? فقط زمانی عملوند سمت راست را برمیگرداند که عملوند سمت چپ null یا undefined باشد.
در غیر این صورت، عملوند سمت چپ برگردانده میشود.
به این ترتیب، اکنون میتوان مقدار پیشفرض را دقیقتر اعمال کرد.
let amount = null;
amount = amount ?? 1;
// => 1
amount = 0;
amount = amount ?? 1;
// => 0
[۱] Undefined, MDN. (۲۰۲۱). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (بازدید در ۴ ژوئن ۲۰۲۱).