على عكس كثير من اللغات الأخرى، يوجد في JavaScript كيانان مختلفان يمثلان غياب قيمة (ذات معنى).
هما null وundefined.
null
تُستخدم القيمة الأولية null كـ«قيمة فارغة» مقصودة للمتغيرات من أي نوع.
let name = null;
// name is intentionally set to "empty" because it is not
// available
يمكنك التحقق مما إذا كان المتغير يحمل القيمة null باستخدام عامل المساواة الصارم ===.
let name = null;
name === null;
// => true
undefined
المتغير الذي لم تُسنَد إليه قيمة يكون من النوع
undefined.1
وهذا يعني أنه بينما تمثل null قيمة فارغة (لكنها قيمة رغم ذلك)، تمثل undefined الغياب التام للقيمة. 🤯
تظهر undefined في سياقات مختلفة.
undefined.undefined.undefined.undefined، إلا إذا كان لهذا الوسيط قيمة افتراضية.let name;
console.log(name);
// => undefined
يمكنك التحقق مما إذا كان المتغير يحمل القيمة undefined باستخدام عامل المساواة الصارم ===.
let name;
name === undefined;
// => true
إذا حاولت استرجاع قيمة متداخلة في كائن لكن المفتاح الأب غير موجود، فسيُلقي JavaScript خطأً.
ولتجنب ذلك بسهولة، أُضيف التسلسل الاختياري إلى مواصفات اللغة في عام 2020.
باستخدام عامل التسلسل الاختياري ?. يمكنك أن تضمن ألا يحاول JavaScript الوصول إلى المفتاح المتداخل إلا إذا لم يكن المفتاح الأب null أو undefined.
وفي غير ذلك، تكون النتيجة undefined.
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.address.zipCode;
// => undefined
obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined
obj.residence?.street;
// => undefined
هناك حالات تريد فيها تطبيق قيمة افتراضية إذا كان المتغير null أو undefined (وفي هذه الحالة فقط).
ولمعالجة ذلك، قُدِّم عامل الدمج الفارغي ?? في عام 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).
تقع على عاتقك مسؤولية توفير أجزاء من نظام المعلومات في مدينة ملاهٍ وصيانتها. وبشكل خاص، أنت مسؤول عن البرنامج الذي يدير الزوار والتذاكر.
أولًا، ستنشئ زائرًا جديدًا في النظام. ثم توفّر دالة لإبطال تذكرة. وفي المهمتين 3 و4، ستعمل على نظام تتبّع التذاكر الذي يساعد على منع التزوير. وأخيرًا، ستساعد في تكييف النظام مع متطلبات قانونية جديدة.
عندما يأتي الزوار إلى مدينة الملاهي للمرة الأولى، يحتاجون إلى التسجيل بإدخال اسمهم وعمرهم في الطرفية والموافقة على الشروط والأحكام.
وبالطبع، يحتاجون أيضًا إلى شراء تذكرة.
ولكل تذكرة معرّف مثل H32AZ123.
اكتب دالة createVisitor تستقبل ثلاثة وسائط.
ينبغي أن تُرجع الدالة كائنًا يحمل هذه المعلومات.
وينبغي أن تُسمّى المفاتيح في الكائن name وage وticketId.
createVisitor('Verena Nardi', 45, 'H32AZ123');
// => { name: 'Verena Nardi', age: 45, ticketId: 'H32AZ123' }
عندما يغادر الناس مدينة الملاهي، تُبطَل تذكرتهم. وإذا عادوا، فيحتاجون إلى شراء تذكرة جديدة. ولتوفير بعض الوقت على الزوار الدائمين، لا يحتاجون إلى التسجيل سوى مرة واحدة، وتبقى معلومات الزائر محفوظة للزيارات اللاحقة.
وهذا يعني أنه عندما يغادر زائر الحديقة، ينبغي إبطال تذكرته فقط، مع بقاء بقية كائن الزائر كما هو.
نفّذ الدالة revokeTicket التي تستقبل كائن زائر، وتضبط معرّف التذكرة على null، ثم تُرجع الكائن بعد ذلك.
const visitor = {
name: 'Verena Nardi',
age: 45,
ticketId: 'H32AZ123',
};
revokeTicket(visitor);
// => { name: 'Verena Nardi', age: 45, ticketId: null }
لمنع التزوير، تكون معرّفات التذاكر فريدة. وبمجرد طباعة تذكرة، يُضاف معرّفها كمفتاح في كائن داخل النظام حتى يمكن تتبّعها.
قبل بيع التذكرة لزائر، تُخزَّن بالقيمة null في كائن تتبّع التذاكر.
وعند بيعها لزائر، يُسنَد اسم الزائر كقيمة لها.
وعندما يشك الموظفون في صلاحية تذكرة، يحتاجون إلى التحقق من حالة التذكرة في النظام.
نفّذ دالة ticketStatus تستقبل كائن التتبّع ومعرّف تذكرة كوسيطين.
ينبغي أن تُرجع إحدى النتائج التالية.
'unknown ticket id' إذا لم يُعثر على المعرّف في كائن التتبّع'not sold' في حال طُبعت التذكرة ولكن لم تُبَع'sold to {name}' حيث {name} هو اسم الزائر إذا بيعت التذكرةconst tickets = {
'0H2AZ123': null,
'23LA9T41': 'Verena Nardi',
};
ticketStatus(tickets, 'RE90VAW7');
// => 'unknown ticket id'
ticketStatus(tickets, '0H2AZ123');
// => 'not sold'
ticketStatus(tickets, '23LA9T41');
// => 'sold to Verena Nardi'
بعد فترة، تصلك ملاحظات من الموظفين بأنهم يريدون أن تكون حالة التذكرة أسهل في الفهم من النظرة الأولى. وهم يريدون فقط رؤية اسم الزائر أو أن التذكرة غير صالحة.
اكتب دالة simpleTicketStatus تستقبل الوسائط نفسها التي تستقبلها ticketStatus في المهمة 3.
وهذه الدالة تُرجع واحدًا فقط من نتيجتين مختلفتين.
'invalid ticket !!!' إذا لم تُبَع التذكرة بعد أو لم يُعثر على المعرّف في كائن التتبّعconst tickets = {
'0H2AZ123': null,
'23LA9T41': 'Verena Nardi',
};
simpleTicketStatus(tickets, '23LA9T41');
// => 'Verena Nardi'
simpleTicketStatus(tickets, '0H2AZ123');
// => 'invalid ticket !!!'
simpleTicketStatus(tickets, 'RE90VAW7');
// => 'invalid ticket !!!'
بسبب متطلبات قانونية جديدة، تحتوي كائنات الزوار المُنشأة حديثًا الآن أيضًا على معلومات مفصّلة عن "الشروط والأحكام العامة" (GTC) التي وافق عليها المستخدم. يمكنك رؤية مثال على كائن الزائر الجديد أدناه.
يحتاج أمناء الصندوق في مدينة الملاهي الآن إلى التحقق مما إذا كان على زائر توقيع إصدار جديد من الشروط والأحكام العامة.
ومن أجل ذلك، نفّذ دالة gtcVersion تستقبل كائن زائر كوسيط وتُرجع إصدار الشروط والأحكام العامة إذا كان متاحًا.
وإذا لم تكن معلومات الإصدار متاحة، فلا ينبغي إرجاع أي شيء.
const visitorNew = {
name: 'Verena Nardi',
age: 45,
ticketId: 'H32AZ123',
gtc: {
signed: true,
version: '2.1',
},
};
gtcVersion(visitorNew);
// => '2.1'
const visitorOld = {
name: 'Verena Nardi',
age: 45,
ticketId: 'H32AZ123',
};
gtcVersion(visitorOld);
// => undefined
سجّل في Exercism لتتعلّم وتتقن JavaScript عبر 37 مفهومًا159 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.