بررسی مقادیر null ،undefined و empty در جاوااسکریپت

در ظاهر، بررسی مقدار null در جاوااسکریپت باید فرآیندی ساده باشد. اما در عمل، همین موضوع می‌تواند حتی توسعه‌دهندگان باتجربه را به اشتباه بیندازد.
برخلاف بسیاری از زبان‌های برنامه‌نویسی که تنها با مقدار null سروکار دارند، در جاوااسکریپت لازم است هم با null و هم با undefined به درستی برخورد کنیم؛ دو مفهومی که با وجود شباهت‌های ظاهری، تفاوت‌های مهمی با یکدیگر دارند.
در این مقاله، ساده‌ترین و کاربردی‌ترین روش‌های بررسی مقادیر null ،undefined و حتی مقادیر empty در جاوااسکریپت را مرور می‌کنیم. اگر به دنبال راهکاری سریع و قابل‌اعتماد هستید، با ما همراه باشید.

چگونه یک تابع بررسی null در جاوااسکریپت بنویسیم؟

در این بخش، روشی سریع و مطمئن برای تشخیص مقادیر null یا undefined را باهم بررسی می‌کنیم.

با یک مثال ساده شروع می‌کنیم. فرض کنید آبجکتی به شکل زیر داریم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var testObject = {
empty: '',
isNull: null,
isUndefined: undefined,
zero: 0
}
>
var testObject = { empty: '', isNull: null, isUndefined: undefined, zero: 0 } >
var testObject = {
    empty: '',
    isNull: null,
    isUndefined: undefined,
    zero: 0
}
>

اکنون تابعی می‌نویسیم که مقدار ورودی را بررسی می‌کند تا ببینیم آیا null است یا نه:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function isNull(value){
if (value == null){
return true
}
else{
return false
}
}
function isNull(value){ if (value == null){ return true } else{ return false } }
function isNull(value){
    if (value == null){
        return true
    }
    else{
        return false
    }
}

برای تست این تابع، مقادیر مختلفی را به آن پاس می‌دهیم و خروجی را بررسی می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
console.log(`
testObject.empty: ${isNull(testObject.empty)}
testObject.isNull: ${isNull(testObject.isNull)}
testObject.isUndefined: ${isNull(testObject.isUndefined)}
zero: ${isNull(testObject.zero)}
`)
console.log(` testObject.empty: ${isNull(testObject.empty)} testObject.isNull: ${isNull(testObject.isNull)} testObject.isUndefined: ${isNull(testObject.isUndefined)} zero: ${isNull(testObject.zero)} `)
console.log(`
    testObject.empty: ${isNull(testObject.empty)}
    testObject.isNull: ${isNull(testObject.isNull)}
    testObject.isUndefined: ${isNull(testObject.isUndefined)}
    zero: ${isNull(testObject.zero)}    
    `)

خروجی چیزی شبیه به این خواهد بود:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
C:\Program Files\nodejs\node.exe .\index.js
testObject.empty: false
testObject.isNull: true
testObject.isUndefined: true
zero: false
C:\Program Files\nodejs\node.exe .\index.js testObject.empty: false testObject.isNull: true testObject.isUndefined: true zero: false
C:\Program Files\nodejs\node.exe .\index.js

    testObject.empty: false
    testObject.isNull: true
    testObject.isUndefined: true
    zero: false

همان‌طور که می‌بینیم، اگر مقدار ورودی null یا undefined باشد، تابع

isNull
isNull مقدار
true
true را برمی‌گرداند. این رفتاری است که معمولاً در زبان‌های دیگر هم مشابه آن را می‌بینیم.

بررسی مقادیر null، undefined یا رشته خالی

اگر بخواهیم بررسی کنیم که یک متغیر null است یا صرفاً مقدار خالی دارد، می‌توانیم از روش زیر استفاده کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function isNullOrEmpty(value){
return !value;
}
function isNullOrEmpty(value){ return !value; }
function isNullOrEmpty(value){
    return !value;
}

این روش مبتنی بر مفهوم «truthiness» در جاوااسکریپت است. مقادیری مثل رشته‌هایی که دارای محتوا هستند یا اعداد بزرگ‌تر از صفر، truthy محسوب می‌شوند و در نتیجه، مقدار

true
true بازمی‌گردانند. در مقابل، رشته‌های خالی، مقدار
false
false تولید می‌کنند.

اما باید در استفاده از این روش کمی با دقت عمل کنیم. فرض کنید در حال اعتبارسنجی یک فرم هستیم. اگر کاربر یک رشته خالی وارد کند، منطقی‌ست که فیلد را «پر نشده» در نظر بگیریم.

اما اگر کاربر عدد ۰ را وارد کند، در این صورت هم مقدار

false
false بازمی‌گردد، در حالی که ممکن است این مقدار کاملاً معتبر باشد. در چنین شرایطی، عملکرد تابع مطابق انتظار ما نخواهد بود. حتی آرایه‌های خالی نیز مقدار
false
false برمی‌گردانند، بنابراین تفاوتی بین آرایه‌ای که اصلاً وجود ندارد و آرایه‌ای که تعریف شده ولی مقدار ندارد، در خروجی این تابع وجود نخواهد داشت؛ که احتمالاً این چیزی نیست که مدنظر ما باشد.

پیچیدگی‌های null و undefined در جاوااسکریپت

در اینترنت صدها مقاله و پرسش در StackOverflow درباره مدیریت null و undefined وجود دارد. علتش این است که رفتار این دو مقدار در جاوااسکریپت برای بسیاری از توسعه‌دهندگان، چه مبتدی و چه حرفه‌ای، گیج‌کننده است. اگر به درستی با آن‌ها برخورد نکنیم، ممکن است باعث اختلال در عملکرد سایت یا برنامه‌های Node.js شود. به همین دلیل، دقت در کار با آن‌ها ضروری است.

پیچیدگی این موضوع به سابقه طولانی جاوااسکریپت هم برمی‌گردد. این زبان که از سال ۱۹۹۵ استفاده می‌شود، امروزه تقریباً در همه وب‌سایت‌ها حضور دارد. بنابراین، تغییر در نحوه مدیریت null یا undefined می‌تواند اختلالاتی در مقیاس بزرگ ایجاد کند.

یکی از دلایل اصلی این چالش، تفاوت جاوااسکریپت با سایر زبان‌هاست. در اغلب زبان‌های برنامه‌نویسی تنها null وجود دارد و در صورت نبود مقدار، به جای بازگرداندن undefined، خطا throw می‌شود. اما در جاوااسکریپت هر دو مفهوم وجود دارند و باید به‌طور جداگانه مدیریت شوند.

برای مثال، اگر چنین کدی در زبان #C بنویسیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
string testString;
Console.WriteLine(testString);
string testString; Console.WriteLine(testString);
string testString;
Console.WriteLine(testString);

کامپایلر خطا می‌دهد و می‌گوید: «استفاده از متغیر محلی مقداردهی‌نشده

testString
testString». یعنی به ما اعلام می‌کند که نمی‌توانیم از متغیری استفاده کنیم که هنوز مقداری به آن داده نشده است؛ به‌عبارتی، مقدار آن undefined است.

در زبان‌هایی مثل C#، عملاً نمی‌توانیم متغیرهایی را که مقداردهی نشده‌اند استفاده کنیم، چون کامپایلر اجازه نمی‌دهد. حتی در شرایط دیگری که ممکن است باعث خطا شود؛ مثل دسترسی به اندیسی در آرایه که خارج از محدوده است؛ باز هم خطا تولید می‌شود. اما در جاوااسکریپت، این عملیات فقط مقدار undefined را برمی‌گرداند.

به عنوان مثال:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let array = [];
console.log(array[5])
let array = []; console.log(array[5])
let array = [];
console.log(array[5])

در اینجا، ما یک آرایه خالی داریم و می‌خواهیم عنصر پنجم آن را چاپ کنیم؛ چیزی که وجود ندارد. نتیجه این کد undefined خواهد بود.

تفاوت بین مقداردهی null و undefined

به‌طور کلی، زمانی که می‌خواهیم بررسی کنیم آیا یک مقدار ممکن است null یا undefined باشد، باید سه وضعیت مختلف را در نظر بگیریم. برای درک بهتر این تفاوت‌ها، تصور کنید که یک جعبه‌ای داریم که نقش متغیر ما را ایفا می‌کند، و هر چیزی که داخل آن قرار می‌دهیم، مقدار اختصاص داده شده به آن متغیر را نشان می‌دهد.

۱- مقداردهی‌شده (Assigned)

در این وضعیت، جعبه وجود دارد و مقداری درون آن قرار گرفته است. صرف‌نظر از این‌که مقدار دقیقاً چیست، اطمینان داریم که متغیر مقداردهی شده و مقدار آن نه null است و نه undefined. بنابراین، یک شئ واقعی درون متغیر وجود دارد.

۲- مقدار null

در این وضعیت، جعبه (متغیر) هنوز وجود دارد، اما خالی است. یعنی متغیر به‌طور صریح مقدار null گرفته که نشان دهنده نبود مقدار است، اما همچنان به عنوان یک مقدار تعریف شده در نظر گرفته می‌شود.

۳- مقدار undefined

در این حالت، اساساً جعبه‌ای وجود ندارد. یعنی متغیر نه تنها مقداری ندارد، بلکه اصلاً مقداردهی هم نشده است. این وضعیت با null تفاوت دارد؛ زیرا در حالت null، متغیر مقداردهی شده است اما مقداری واقعی درون آن وجود ندارد.

جمع‌بندی

در اغلب موارد، بررسی مقدار null به تنهایی کافی به نظر می‌رسد. اما از آنجا که در جاوااسکریپت هر دو مقدار null و undefined وجود داشته و معانی متفاوتی دارند، لازم است دقیقاً بدانیم چه نوع بررسی‌ای مدنظر ماست و بر همان اساس عمل کنیم.
با توجه به این که null یک مقدار falsey است، ممکن است به سادگی از عبارتی مانند

if (!value)
if (!value) برای انجام بررسی استفاده کنیم. اما همان‌طور که دیدیم، این روش می‌تواند به اشتباه مقدارهایی مانند رشته خالی (“”) یا آرایه خالی ([]) را نیز شامل شود؛ در حالی که شاید هدف ما این نباشد.
شناخت دقیق تفاوت‌های کلیدی میان این سه وضعیت، به ما کمک می‌کند تا کدی دقیق‌تر و قابل‌اعتمادتر بنویسیم؛ کدی که از رفتارهای غیرمنتظره جلوگیری کند و در نهایت کیفیت پروژه را بالا ببرد، حتی اگر این دقت زمان بیشتری از ما بگیرد.

دیدگاه‌ها:

افزودن دیدگاه جدید