تبدیل نوع داده: Type Conversion و Type Coercion

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

  • درک تفاوت بین Type Conversion (تبدیل صریح) و Type Coercion (تبدیل ضمنی)
  • آشنایی با روش‌های صریح تبدیل نوع در جاوااسکریپت
  • فهم قوانین اصلی Type Coercion در عملگرهای رایج
  • توانایی پیش‌بینی نتیجه‌ی عملیات‌هایی که بین انواع مختلف داده انجام می‌شوند

مقدمه

جاوااسکریپت یک زبان با تایپ پویا (Dynamically Typed) است؛ یعنی نوع یک متغیر از قبل مشخص نیست و در زمان اجرا تعیین می‌شود. یکی از پیامدهای این ویژگی، این است که جاوااسکریپت گاهی خودش، بدون اینکه از او خواسته باشیم، نوع داده را تغییر می‌دهد. این رفتار می‌تواند نتایج غیرمنتظره‌ای تولید کند، مگر اینکه قوانین آن را دقیق بدانیم.

Type Conversion — تبدیل صریح

وقتی خودمان آگاهانه نوع یک مقدار را تغییر می‌دهیم، به آن Type Conversion می‌گویند:

let numText = "25";

let num = Number(numText);       // تبدیل صریح به Number
let str = String(100);           // تبدیل صریح به String
let bool = Boolean(1);           // تبدیل صریح به Boolean

console.log(num, typeof num);    // 25 "number"
console.log(str, typeof str);    // "100" "string"
console.log(bool, typeof bool);  // true "boolean"

در این مثال، از توابع Number()، String() و Boolean() برای تبدیل آگاهانه‌ی نوع استفاده شده است. این کنترل کاملاً در دست برنامه‌نویس است.

Type Coercion — تبدیل ضمنی

اما گاهی جاوااسکریپت بدون درخواست مستقیم ما، نوع یک مقدار را برای انجام یک عملیات تغییر می‌دهد. به این رفتار Type Coercion می‌گویند:

console.log("5" + 1);   // "51"
console.log("5" - 1);   // 4
console.log("5" * "2"); // 10

تحلیل کد

در خط اول، عملگر + وقتی یکی از دو مقدار رشته باشد، مقدار دیگر را هم به رشته تبدیل می‌کند و آن‌ها را به هم می‌چسباند؛ به همین دلیل "5" + 1 برابر "51" می‌شود، نه 6. اما عملگرهای - و * رفتار متفاوتی دارند: چون این عملگرها فقط معنای عددی دارند، جاوااسکریپت هر دو طرف را به Number تبدیل می‌کند و سپس عملیات را انجام می‌دهد.

قانون کلی عملگر +

عملگر + در جاوااسکریپت دو نقش دارد: جمع عددی و اتصال رشته‌ای (Concatenation). قانون تعیین‌کننده این است:

  • اگر حداقل یکی از دو طرف رشته باشد، عملیات به اتصال رشته‌ای تبدیل می‌شود.
  • در غیر این صورت، عملیات جمع عددی انجام می‌شود.
console.log(1 + 2);        // 3
console.log("1" + 2);      // "12"
console.log(1 + "2" + 3);  // "123"
console.log(1 + 2 + "3");  // "33"

در دو مثال آخر، ترتیب ارزیابی از چپ به راست اهمیت زیادی دارد؛ در حالت 1 + 2 + "3"، ابتدا 1 + 2 که هر دو عدد هستند محاسبه شده و برابر 3 می‌شود، سپس 3 + "3" به رشته‌ی "33" تبدیل می‌شود.

تبدیل ضمنی به Boolean

در شرط‌ها (مثل if)، جاوااسکریپت مقادیر را به‌صورت ضمنی به Boolean تبدیل می‌کند. مقادیری که در این تبدیل به false می‌رسند، Falsy نامیده می‌شوند:

Boolean(0);          // false
Boolean("");         // false
Boolean(null);       // false
Boolean(undefined);  // false
Boolean(NaN);        // false
Boolean(false);      // false

هر مقدار دیگری غیر از موارد بالا، Truthy در نظر گرفته می‌شود؛ حتی مقادیری مثل "0" (رشته‌ی حاوی صفر) یا [] (آرایه‌ی خالی)، چون خودِ رشته و خودِ آرایه Truthy هستند، صرف‌نظر از محتوایشان.

if ("0") {
  console.log("این اجرا می‌شود"); // چون "0" یک رشته‌ی غیرخالی و Truthy است
}

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

  • تصور اینکه "5" + 1 نتیجه‌ی عددی 6 می‌دهد؛ درحالی‌که نتیجه رشته‌ی "51" است.
  • گمان کردن این‌که "0" یا [] مقادیر Falsy هستند، درحالی‌که هر دو Truthy‌اند.
  • وابسته شدن بیش از حد به Type Coercion به‌جای تبدیل صریح، که خوانایی کد را کاهش می‌دهد.

Best Practices

  • در مواردی که نیاز به تبدیل نوع دارید، همیشه از Type Conversion صریح (مثل Number() یا String()) استفاده کنید تا رفتار کد قابل پیش‌بینی باشد.
  • روی Type Coercion برای منطق مهم برنامه تکیه نکنید؛ اگرچه دانستن قوانین آن برای خواندن و دیباگ کردن کدهای دیگران ضروری است.

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

درک Type Coercion پیش‌نیاز فهم دقیق تفاوت == و === است که در درس بعدی بررسی می‌کنیم؛ چون عملگر == دقیقاً بر پایه‌ی همین قوانین تبدیل ضمنی عمل می‌کند.

جمع‌بندی

Type Conversion به تبدیل آگاهانه و صریح نوع داده گفته می‌شود، درحالی‌که Type Coercion به تبدیل خودکار و ضمنی توسط جاوااسکریپت اشاره دارد. عملگر + در این میان رفتار خاصی دارد: در صورت وجود رشته، اتصال رشته‌ای انجام می‌دهد. شناخت این قوانین برای پیش‌بینی درست رفتار کد، به‌ویژه در شرط‌ها و عملیات ریاضی، ضروری است.