معرفة نوع قطعة البيانات أمر مهم غالبًا لكي يعمل الكود بسلاسة ودون أخطاء.
لدى Javascript عدة أساليب للتحقق من نوع قيمة أو كائن.
قد تكون آليات فحص الأنواع في 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
يحتوي صنف 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
سيُرجع 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
لقد وظّفك مركز لإعادة التدوير. بسبب نقص المساحة، تُوضع جميع المنتجات على الحزام الناقل نفسه، لكن هذا أدى إلى اختلاط مواد مختلفة معًا، مما جعلها غير قابلة للاستخدام. لحل هذه المشكلة، أُوكلت إليك مهمة إنشاء دوال لتحديد نوع المنتج.
نفّذ الدالة isBoolean، التي تتحقق مما إذا كانت القيمة قيمة منطقية.
isBoolean(true);
// => true
isBoolean(null);
// => false
نفّذ الدالة isNumber، التي تتحقق مما إذا كانت القيمة number أو bigint منتهية، أي ليست NaN أو Infinity.
أحيانًا، يفشل جهاز قراءة المعرّفات ويقرأ قيمة غير رقمية على أنها NaN (ليس عددًا) أو Infinity.
وينبغي أن تتعامل دالتك مع هذا بشكل صحيح أيضًا.
isNumber(42);
// => true
isNumber('Hello, World!');
// => false
isNumber(42n);
// => true
isNumber(NaN);
// => false
نفّذ الدالة isObject، التي ينبغي أن تتحقق مما إذا كانت القيمة كائنًا.
على الحزام الناقل، null ليس شيئًا ولا يُعتبر كائنًا.
isObject({ greeting: 'Hello' });
// => true
isObject(25n);
// => false
نفّذ الدالة isNumericString، التي ينبغي أن تتحقق مما إذا كانت القيمة سلسلة نصية تتكوّن فقط من أرقام، أو من إشارة ناقص متبوعة بأرقام تشير إلى عدد سالب.
يجب أن نتعامل مع الأعداد الصحيحة فقط؛ فلا تُعتبر الأعداد العشرية رقمية في هذا الفحص الخاص بروبوت إعادة التدوير.
isNumericString(42);
// => false
isNumericString('42');
// => true
isNumericString('Hi!');
// => false
نفّذ الدالة isElectronic، التي تتحقق مما إذا كان الكائن نسخة من الصنف ElectronicDevice المزوّد أو من أحد أصنافه الفرعية.
class Duck {
//...
}
class WashingMachine extends ElectronicDevice {
//...
}
isElectronic(new Duck());
// => false
isElectronic(new WashingMachine());
// => true
نفّذ الدالة isNonEmptyArray، التي تتحقق مما إذا كانت القيمة مصفوفة غير فارغة.
isNonEmptyArray([1, 2, 3]);
// => true
isNonEmptyArray([]);
// => false
نفّذ الدالة isEmptyArray، التي تتحقق مما إذا كانت القيمة مصفوفة فارغة.
isEmptyArray([1, 2, 3]);
// => false
isEmptyArray([]);
// => true
type
نفّذ الدالة hasType، التي تتحقق مما إذا كان للكائن خاصية أو طريقة باسم type.
class Keyboard(){
type(){
// ...
}
}
hasType({ type:"car", color:"red" })
// => true
hasType({ color:"green" })
// => false
hasType(new Keyboard())
// => true
id
نفّذ الدالة assertHasId، التي سترمي خطأ من نوع Error إذا كان الكائن يفتقد الخاصية id.
وإذا كان للكائن الخاصية id بالفعل، فلا ينبغي أن تُرجع أي شيء.
assertHasId({ id: 42, color: 'red' });
// => undefined
assertHasId({ color: 'green' });
// Error: "Object is missing the 'id' property"
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
type معرّفةنفّذ الدالة hasDefinedType، التي تتحقق مما إذا كان للكائن خاصية type لا تساوي undefined.
hasDefinedType({ type: undefined, color: 'red' });
// => false
hasDefinedType({ type: 'car', color: 'green' });
// => true
سجّل في Exercism لتتعلّم وتتقن JavaScript عبر 37 مفهومًا159 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.