المسارات
/
JavaScript
JavaScript
/
التمارين
/
روبوت إعادة التدوير
روبوت إعادة التدوير

روبوت إعادة التدوير

تمرين تعلّمي

مقدمة

معرفة نوع قطعة البيانات أمر مهم غالبًا لكي يعمل الكود بسلاسة ودون أخطاء.

لدى Javascript عدة أساليب للتحقق من نوع قيمة أو كائن.

Note

قد تكون آليات فحص الأنواع في Javascript غير موثوقة إلى حد ما.

للحصول على أمان أفضل للأنواع وأنواع أقوى، يُستحسن أن تستخدم TypeScript، وهي لغة مبنية على JavaScript، لكن بصياغة الأنواع الخاصة بلغة ذات أنواع ثابتة.

عامل typeof

يُرجع عامل typeof نوع الطرف الخاص به. الناتج هو سلسلة نصية تطابق اسم أحد أنواع البيانات الأولية، باستثناء "null". ويمكن أن يكون أيضًا "function" أو "object".

typeof undefined;
// => "undefined"

typeof true;
// => "boolean"

typeof 42;
// => "number"

typeof 'Hello, World!';
// => "string"

typeof function () {
  return 'Hello, World';
};
// => "function"

typeof [1, 2, 3, 4];
// => "object"

typeof { city: 'Stockholm', country: 'Sweden' };
// => "object"

لأسباب [تاريخية][typeof null is "object"].

عامل instanceof

للتحقق من نوع كائن، يمكنك استخدام عامل instanceof. وهو يُقيّم إلى boolean بحسب ما إذا كان الطرف الثاني مُدرجًا في سلسلة النماذج الأولية للطرف الأول. وللتوضيح، سيُرجع instanceof ما إذا كان الطرف الأول نسخة من الطرف الثاني أو من إحدى أصنافه الفرعية. يعمل instanceof على الكائنات فقط.

class Beverage {
  // ...
}

// The Coffee class is a child of the Beverage class.
class Coffee extends Beverage {
  // ...
}

const java = new Coffee();

java instanceof Coffee;
// => true

java instanceof Beverage;
// => true
Advanced

يحتوي صنف Array على طريقة تُسمى Array.isArray() تتحقق مما إذا كان وسيطها مصفوفة.

بينما لا يعمل instanceof Array مع مصفوفة أُنشئت في بيئة مختلفة مثل iframe في صفحة ويب، فإن Array.isArray() يعمل.

وذلك لأن صنف Array له دالة إنشاء مختلفة في كل بيئة، ولكل iframe بيئته الخاصة، ما يعني أن الدالة في سلسلة النماذج الأولية ستكون مختلفة، فيفشل instanceof Array. ويستطيع Array.isArray() تجاهل ذلك، وينبغي استخدامه دائمًا كلما أمكن.

ويمكنه أيضًا تجاوز النتائج الإيجابية الكاذبة حين لا يكون الكائن في الحقيقة مصفوفة، وإنما يحوي Array في سلسلة النماذج الأولية الخاصة به فقط.

({ __proto__: Array.prototype }) instanceof Array
// => true

Array.isArray({ __proto__: Array.prototype })
// => false

عامل in

يُحدد عامل in ما إذا كان الطرف الأول خاصية من خصائص الطرف الثاني. وهو لا يتحقق من أن للخاصية قيمة معرَّفة. فالخاصية المضبوطة على undefined سيكتشفها in مع ذلك.

class Coffee {
  constructor() {
    this.temperature = 'hot';
    this.isDarkMatter = undefined;
  }

  coolDown() {
    this.temperature = 'warm';
  }
}

const espresso = new Coffee();

'temperature' in espresso;
// => true

'color' in espresso;
// => false

'isDarkMatter' in espresso;
// => true
Note

سيُرجع in القيمة true للخصائص والطرق الموروثة.

"coolDown" in espresso
// => true

"constructor" in espresso
// => true

لتجنّب ذلك، استخدم Object.hasOwn() بدلًا منه

دالة Object.hasOwn()

تُرجع طريقة Object.hasOwn() ما إذا كان الكائن المحدد يملك الخاصية المعطاة (فهي ليست موروثة ولا طريقة).

class Coffee {
  constructor() {
    this.temperature = 'hot';
  }

  coolDown() {
    this.temperature = 'warm';
  }
}
const cappuccino = new Coffee();

Object.hasOwn(cappucino, 'temperature');
// => true

Object.hasOwn(cappucino, 'constructor');
// => false

Object.hasOwn(cappucino, 'coolDown');
// => false

التعليمات

التعليمات

لقد وظّفك مركز لإعادة التدوير. بسبب نقص المساحة، تُوضع جميع المنتجات على الحزام الناقل نفسه، لكن هذا أدى إلى اختلاط مواد مختلفة معًا، مما جعلها غير قابلة للاستخدام. لحل هذه المشكلة، أُوكلت إليك مهمة إنشاء دوال لتحديد نوع المنتج.

1. تحقّق مما إذا كانت القيمة قيمة منطقية

نفّذ الدالة isBoolean، التي تتحقق مما إذا كانت القيمة قيمة منطقية.

isBoolean(true);
// => true

isBoolean(null);
// => false

2. تحقّق مما إذا كانت القيمة عددًا.

نفّذ الدالة isNumber، التي تتحقق مما إذا كانت القيمة number أو bigint منتهية، أي ليست NaN أو Infinity.

أحيانًا، يفشل جهاز قراءة المعرّفات ويقرأ قيمة غير رقمية على أنها NaN (ليس عددًا) أو Infinity. وينبغي أن تتعامل دالتك مع هذا بشكل صحيح أيضًا.

isNumber(42);
// => true

isNumber('Hello, World!');
// => false

isNumber(42n);
// => true

isNumber(NaN);
// => false

3. تحقّق مما إذا كانت القيمة كائنًا

نفّذ الدالة isObject، التي ينبغي أن تتحقق مما إذا كانت القيمة كائنًا. على الحزام الناقل، null ليس شيئًا ولا يُعتبر كائنًا.

isObject({ greeting: 'Hello' });
// => true

isObject(25n);
// => false

4. تحقّق مما إذا كانت السلسلة النصية رقمية

نفّذ الدالة isNumericString، التي ينبغي أن تتحقق مما إذا كانت القيمة سلسلة نصية تتكوّن فقط من أرقام، أو من إشارة ناقص متبوعة بأرقام تشير إلى عدد سالب. يجب أن نتعامل مع الأعداد الصحيحة فقط؛ فلا تُعتبر الأعداد العشرية رقمية في هذا الفحص الخاص بروبوت إعادة التدوير.

isNumericString(42);
// => false

isNumericString('42');
// => true

isNumericString('Hi!');
// => false

5. تحقّق مما إذا كان الكائن إلكترونيًا

نفّذ الدالة isElectronic، التي تتحقق مما إذا كان الكائن نسخة من الصنف ElectronicDevice المزوّد أو من أحد أصنافه الفرعية.

class Duck {
  //...
}

class WashingMachine extends ElectronicDevice {
  //...
}

isElectronic(new Duck());
// => false

isElectronic(new WashingMachine());
// => true

6. تحقّق مما إذا كانت القيمة مصفوفة غير فارغة

نفّذ الدالة isNonEmptyArray، التي تتحقق مما إذا كانت القيمة مصفوفة غير فارغة.

isNonEmptyArray([1, 2, 3]);
// => true

isNonEmptyArray([]);
// => false

7. تحقّق مما إذا كانت القيمة مصفوفة فارغة

نفّذ الدالة isEmptyArray، التي تتحقق مما إذا كانت القيمة مصفوفة فارغة.

isEmptyArray([1, 2, 3]);
// => false

isEmptyArray([]);
// => true

8. تحقّق مما إذا كان للكائن خاصية أو طريقة باسم type

نفّذ الدالة hasType، التي تتحقق مما إذا كان للكائن خاصية أو طريقة باسم type.

class Keyboard(){
  type(){
    // ...
  }
}
hasType({ type:"car", color:"red" })
// => true

hasType({ color:"green" })
// => false

hasType(new Keyboard())
// => true

9. ارمِ خطأً إذا لم يكن للكائن خاصية أو طريقة باسم id

نفّذ الدالة assertHasId، التي سترمي خطأ من نوع Error إذا كان الكائن يفتقد الخاصية id.

وإذا كان للكائن الخاصية id بالفعل، فلا ينبغي أن تُرجع أي شيء.

assertHasId({ id: 42, color: 'red' });
// => undefined

assertHasId({ color: 'green' });
// Error: "Object is missing the 'id' property"

10. تحقّق مما إذا كان للكائن خاصية باسم id

نفّذ الدالة hasIdProperty، التي تتحقق مما إذا كان للكائن خاصية id.

class SimpleData {
  constructor() {
    this.number = '42';
    this.id = 'BC269327FE1D9B95';
  }
}

class StealingData extends SimpleData {}

class MethodData {
  constructor() {
    this.number = '42';
    this._id = 'BC269327FE1D9B95';
  }

  get id() {
    return this._id;
  }
}

hasIdProperty(new SimpleData());
// => true

hasIdProperty(new MethodData());
// => false

hasIdProperty(new StealingData());
// => false

11. تحقّق مما إذا كان للكائن خاصية type معرّفة

نفّذ الدالة hasDefinedType، التي تتحقق مما إذا كان للكائن خاصية type لا تساوي undefined.

hasDefinedType({ type: undefined, color: 'red' });
// => false

hasDefinedType({ type: 'car', color: 'green' });
// => true
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
JavaScript Exercism

مستعد لبدء روبوت إعادة التدوير؟

سجّل في Exercism لتتعلّم وتتقن JavaScript عبر 37 مفهومًا159 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.