دانستن این که نوع یک داده چیست، اغلب برای اجرای روان و بدون خطای کد بسیار مهم است.
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"
به دلایل تاریخی.
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 نیست و فقط 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 را پیادهسازی کنید که در صورت نداشتن ویژگی id در یک شیء، یک Error پرتاب میکند.
اگر شیء ویژگی 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 تمرین و مربیگری انسانی واقعی یاد بگیرید و در آن استاد شوید، همهی اینها رایگان.