شناسایی نوع مقادیر با typeof و instanceof

اهداف یادگیری

  • مرور و تثبیت کاربرد عملگر typeof
  • آشنایی با محدودیت‌های typeof در تشخیص Reference Types
  • یادگیری عملگر instanceof و نحوه‌ی کارکرد آن
  • توانایی انتخاب ابزار مناسب برای بررسی نوع یک مقدار

مقدمه

در طول درس‌های قبل، چند بار از typeof برای بررسی نوع یک مقدار استفاده کردیم. در این درس، این عملگر را با جزئیات کامل بررسی می‌کنیم، محدودیت‌های آن را می‌شناسیم و با عملگر دوم، یعنی instanceof، آشنا می‌شویم که برای بررسی نوع Reference Types کاربرد دارد.

typeof — بررسی کامل

عملگر typeof نوع یک مقدار Primitive را به‌صورت رشته برمی‌گرداند:

console.log(typeof "سلام");     // "string"
console.log(typeof 25);          // "number"
console.log(typeof true);        // "boolean"
console.log(typeof undefined);   // "undefined"
console.log(typeof Symbol());    // "symbol"
console.log(typeof 10n);         // "bigint"

محدودیت‌های typeof

مشکل اصلی typeof زمانی خودش را نشان می‌دهد که با Reference Types سروکار داشته باشیم:

console.log(typeof {});          // "object"
console.log(typeof []);          // "object"
console.log(typeof null);        // "object"
console.log(typeof function(){});// "function"

همان‌طور که مشاهده می‌کنید، typeof نمی‌تواند بین یک شیء معمولی و یک آرایه تمایز قائل شود؛ هر دو "object" برمی‌گردانند. تنها استثنای جالب، تابع است که typeof برای آن مقدار "function" برمی‌گرداند، هرچند که تابع هم در جاوااسکریپت نوعی شیء محسوب می‌شود.

بررسی آرایه با Array.isArray

از آنجا که typeof نمی‌تواند آرایه را تشخیص دهد، جاوااسکریپت متد مجزایی برای این کار در اختیار می‌گذارد:

console.log(Array.isArray([1, 2, 3])); // true
console.log(Array.isArray({}));        // false

instanceof چیست؟

عملگر instanceof بررسی می‌کند که آیا یک شیء، نمونه‌ای (Instance) از یک نوع خاص است یا نه:

let numbers = [1, 2, 3];
let user = { name: "علی" };

console.log(numbers instanceof Array);   // true
console.log(numbers instanceof Object);  // true
console.log(user instanceof Array);      // false
console.log(user instanceof Object);     // true

تحلیل کد

نکته‌ی جالب اینجاست که numbers instanceof Object نیز true است؛ چون در جاوااسکریپت، آرایه نوعی خاص از شیء محسوب می‌شود. به بیان دیگر، هر آرایه یک شیء هم هست، اما هر شیء لزوماً یک آرایه نیست. دلیل دقیق این رفتار به مفهوم Prototype Chain برمی‌گردد که در فصل مربوط به Prototype به‌طور کامل بررسی خواهد شد؛ در همان‌جا خواهید دید که instanceof در واقع بررسی می‌کند که آیا یک نوع خاص در زنجیره‌ی Prototype شیء موردنظر وجود دارد یا نه.

جدول مقایسه‌ی typeof و instanceof

ویژگیtypeofinstanceof
کاربرد اصلیتشخیص Primitive Typesتشخیص نوع Reference Types
تشخیص آرایه از شیءخیربله
خروجیرشته (مثل "string")Boolean (true/false)
کار با nullنتیجه‌ی نادرست ("object")کاربردی ندارد

اشتباهات رایج

  • استفاده از typeof برای تشخیص آرایه؛ درحالی‌که همیشه "object" برمی‌گرداند و باید از Array.isArray() استفاده کرد.
  • تصور اینکه instanceof برای مقادیر Primitive هم به همان شکل کار می‌کند؛ درحالی‌که این عملگر عمدتاً برای Reference Types کاربرد دارد.
  • فراموش کردن این‌که هر آرایه از نظر instanceof Object نیز مقدار true می‌دهد.

Best Practices

  • برای بررسی Primitive Types از typeof استفاده کنید.
  • برای بررسی آرایه بودن یک مقدار، همیشه از Array.isArray() استفاده کنید، نه typeof.
  • از instanceof برای بررسی تعلق یک شیء به یک Class یا Constructor خاص استفاده کنید.

ارتباط با سایر مفاهیم

درک عملکرد instanceof به‌طور کامل، نیازمند آشنایی با Prototype Chain است که در فصل‌های بعدی به آن می‌پردازیم. همچنین، ترکیب typeof و Array.isArray ابزار اصلی شما برای بررسی نوع داده در سراسر این دوره خواهد بود.

جمع‌بندی

عملگر typeof برای شناسایی Primitive Types مناسب است، اما در تشخیص دقیق Reference Types مثل آرایه محدودیت دارد. عملگر instanceof برای بررسی تعلق یک شیء به یک نوع خاص استفاده می‌شود و برای تشخیص آرایه از شیء معمولی، بهترین گزینه Array.isArray() است.