على عكس كثير من اللغات الأخرى، توجد في 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.1
وهذا يعني أنه بينما يمثّل 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
يمكنك التحقق مما إذا كان المتغير undefined باستخدام عامل المساواة الصارمة === أو عامل typeof.
let name;
name === undefined;
// => true
typeof name === 'undefined';
// => true
لا يُنصح بإسناد undefined إلى متغير يدويًا؛ استخدم null بدلًا من ذلك دائمًا لتوضيح أنك ضبطت قيمة فارغة بشكل مقصود.
كما ذُكر أعلاه، فإن الوصول إلى مفتاح غير موجود في كائن يُرجع undefined في JavaScript.
ومع ذلك، إذا حاولت استرجاع قيمة متداخلة ولم يكن المفتاح الأب موجودًا، فإن تقييم المفتاح المتداخل يُنفَّذ على undefined ويؤدي إلى TypeError: Cannot read property ... of undefined.
نظريًا، ستحتاج دائمًا إلى التحقق من وجود المفتاح الأب قبل أن تحاول استرجاع المفتاح المتداخل.
كان هذا يُفعَل غالبًا باستخدام عامل AND &&، لكن مع القيم المتداخلة بعمق يؤدي هذا إلى تعبيرات طويلة جدًا.
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
لحل هذه المشكلة، أُضيف التسلسل الاختياري إلى مواصفات اللغة في عام 2020.
باستخدام عامل التسلسل الاختياري ?. يمكنك ضمان ألا تحاول 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
لمعالجة ذلك، أُدخل عامل الدمج الصفري ??.
وكما هو الحال مع التسلسل الاختياري، أُضيف إلى مواصفات اللغة في عام 2020.
يُرجع عامل الدمج الصفري ?? الطرف الأيمن فقط عندما يكون الطرف الأيسر null أو undefined.
وإلا فيُرجع الطرف الأيسر.
وبهذا، يمكن الآن تطبيق قيمة افتراضية بشكل أكثر تحديدًا.
let amount = null;
amount = amount ?? 1;
// => 1
amount = 0;
amount = amount ?? 1;
// => 0
[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (تاريخ الوصول: 4 يونيو 2021).