Type Casting (تبدیل نوع داده) در جاوااسکریپت

آموزش کامل، از پایه تا پیشرفته + مثال‌های کاربردی واقعی (۲۰۲۶)

مقدمه

در جاوااسکریپت، بیشتر خطاهای منطقی، رفتارهای عجیب و باگ‌های پنهان از عدم شناخت درست تبدیل نوع داده (Type Casting) به‌وجود می‌آیند.

بنابراین اگر Type Casting را عمیق و عملی یاد بگیرید:

• شرایط شرطی‌تان دقیق‌تر می‌شود

• کار با فرم و ورودی کاربر قابل اعتماد می‌شود

• کار با API، LocalStorage و URLها آسان می‌شود

• رفتار مقایسه‌ها (== و ===) را کاملاً می‌فهمید

• از Type Coercionهای خطرناک جلوگیری می‌کنید

این مقاله همه چیز را خیلی ساده، کاربردی و پروژه‌محور توضیح می‌دهد؛ تمرکز بر موضوعات واقعی:

• تبدیل رشته به عدد

• تبدیل ورودی‌ها

• تبدیل داده‌های API

• تبدیل بولیین

• رفتارهای عجیب جاوااسکریپت (😅)

• روش درست و حرفه‌ای

برویم سر اصل مطلب.

بخش ۱: Type Casting چیست؟

Type Casting یعنی اینکه نوع یک داده را تغییر دهیم.

در جاوااسکریپت دو نوع تبدیل داریم:

۱) Explicit Type Casting

تبدیل صریح و توسط خود برنامه‌نویس

مثل:

Number("10")
String(20)
Boolean(1)

۲) Implicit Type Coercion

تبدیل خودکار توسط جاوااسکریپت

مثل:

"10" * 2 // می‌شود 20
"10" + 2 // می‌شود "102"

در این مقاله هردو را کامل یاد می‌گیرید.

بخش ۲: چرا باید Type Casting را بلد باشیم؟ (مثال‌های واقعی پروژه‌ای)

مثال ۱: فرم ثبت‌نام

کاربر مقدار سن را وارد می‌کند:

نمایش کد

<input id="age" type="number">

مقدار دریافتی:

const age = document.getElementById("age").value;
console.log(typeof age); // string

اگر تبدیل نکنید:

• مقایسه‌ها اشتباه

• شرط‌ها اشتباه

• API خطا می‌دهد

مثال ۲: API و JSON

داده‌های دریافتی:

{
  "id": "12",
  "price": "56000",
  "available": "true"
}

اما ما نیاز داریم:

• id → number

• price → number

• available → boolean

مثال ۳: LocalStorage

تمام اطلاعات در LocalStorage به صورت string ذخیره می‌شود.

بخش ۳: تبدیل صریح (Explicit Conversion)

۳.۱ تبدیل به عدد: Number()

این بخش یکی از مهم‌ترین‌های Type Casting است.

Number("10")  // 10
Number("10.5") // 10.5
Number("") // 0
Number(true) // 1
Number(false) // 0
Number("Hi") // NaN

مثال کاربردی: قیمت ورودی کاربر

const price = Number(priceInput.value);

اگر تبدیل نکنید و بنویسید:

total += priceInput.value;

نتیجه:

"20000" + "30000" = "2000030000" 😱

مثال پروژه‌ای سبد خرید

let total = 0;
const price = Number(product.price);

total += price;

۳.۲ تبدیل به عدد با parseInt و parseFloat

parseInt("20px") // 20
parseFloat("20.5px") // 20.5

تفاوت مهم:

• Number(“20px”) → NaN

• parseInt(“20px”) → 20

کاربرد واقعی: ورودی واحد اندازه

const width = parseInt("250px"); // 250

بخش ۴: تبدیل به رشته (String)

String(10) // "10"
String(true) // "true"
String(null) // "null"

پرکاربردترین روش:

(10).toString()

کاربرد واقعی: پیام‌های UI

let message = "Your score is " + score.toString();

بخش ۵: تبدیل به Boolean – یکی از پرکاربردترین بخش‌ها

جاوااسکریپت ۷ مقدار falsy دارد:

• 0

• “”

• null

• undefined

• false

• NaN

• 0n

هر چیز دیگری true است.

تبدیل صریح:

Boolean("") // false
Boolean("hello") // true
Boolean(0) // false
Boolean(1) // true

مثال واقعی: فرم ثبت‌نام

if (!Boolean(username)) {
    alert("Username is required");
}

نسخه کوتاه‌تر:

if (!username) ...

بخش ۶: Implicit Type Coercion (تبدیل خودکار)

اینجاست که رفتارهای عجیب جاوااسکریپت ظاهر می‌شود.

۶.۱ تبدیل خودکار در عملیات ریاضی

"10" * 2 // 20
"10" - 2 // 8
"10" / 2 // 5

اما:

"10" + 2 // "102"

چرا؟

چون اگر یکی از طرفین string باشد، + تبدیل به عملیات الحاق رشته می‌شود.

۶.۲ مثال واقعی: نمایش تعداد محصولات

let count = "5";
count = count + 1;
console.log(count); // "51" 😅

راه‌حل:

count = Number(count) + 1;

بخش ۷: تبدیل بولی در عملیات شرطی

در شرط‌ها، داده‌ها به boolean تبدیل می‌شوند.

مثال:

if ("Hello") console.log("Yes"); // Yes
if (0) console.log("No"); // اجرا نمی‌شود

مثال واقعی پروژه: چک کردن ورودی فرم

if (!email) {
    showError("Enter your email");
}

بخش ۸: تبدیل در مقایسه‌ها (== و ===)

=== (برابری دقیق)

هیچ تبدیل نوعی انجام نمی‌دهد.

10 === "10" // false

== (خطرناک!)

تبدیل خودکار انجام می‌دهد.

10 == "10" // true

مثال واقعی: خطای معروف در فرم‌ها

if (userAge == "") { ... }

اگر userAge برابر 0 باشد:

0 == "" // true 😱

راه درست:

if (userAge === "") ...

بخش ۹: تبدیل خودکار عجیب (نوع دعوای همیشگی جاوااسکریپت!)

این‌ها را حتماً باید بدانید:

[] == ""  // true
[] == 0   // true
[1] == 1  // true
null == undefined // true

بخش ۱۰: مثال‌های واقعی از دنیای پروژه

مثال ۱: API که مقدار عدد را رشته می‌دهد

دریافتی:

{
  "price": "20000"
}

در پروژه:

const price = Number(data.price);
total += price;

مثال ۲: LocalStorage

localStorage.setItem("count", 10);

بازیابی:

const count = localStorage.getItem("count");
console.log(typeof count); // string

راه درست:

const count = Number(localStorage.getItem("count"));

مثال ۳: فرم ورود کاربر

const age = Number(ageInput.value);

if (age >= 18) {
    showAdultSection();
}

مثال ۴: فیلتر محصولات

const min = Number(minInput.value);
const max = Number(maxInput.value);

products.filter(p => p.price >= min && p.price <= max);

مثال ۵: تبدیل داده‌های Query String

const params = new URLSearchParams(location.search);
const page = Number(params.get("page"));

بخش ۱۱: روش‌های حرفه‌ای تبدیل نوع داده (Best Practices – 2026)

✓ همیشه از Number() استفاده کنید

✓ از parseInt فقط برای متون مخلوط (مثل “250px”)

✓ برای بولین‌ها از Boolean() یا !! استفاده کنید

✓ هیچ‌وقت به == اعتماد نکنید

✓ داده‌های ورودی و LocalStorage را همیشه تبدیل کنید

✓ برای boolean از مقادیر مستقیم کاربر اعتماد نکنید (“false” → true!)

بخش ۱۲: الگوی حرفه‌ای Validation ورودی‌ها

مثلاً برای فیلد قیمت:

function normalizePrice(value) {
    const num = Number(value);
    return isNaN(num) ? 0 : num;
}

بخش ۱۳: تمرین پروژه‌ای – سیستم مدیریت کاربر

function normalizeUser(data) {
    return {
        id: Number(data.id),
        age: Number(data.age),
        active: Boolean(data.active),
        name: String(data.name)
    }
}

const user = normalizeUser({
    id: "12",
    age: "19",
    active: "true",
    name: "Sara"
});

console.log(user);

جمع‌بندی نهایی

در این مقاله یاد گرفتید:

• Type Casting چیست

• تفاوت Explicit و Implicit

• تبدیل رشته به عدد

• تبدیل بولین، رشته، عدد و آبجکت

• رفتارهای عجیب جاوااسکریپت

• کاربرد در پروژه‌های واقعی (API، فرم، LocalStorage، Query Params)

• بهترین روش‌ها و استانداردها

Type Casting یکی از پایه‌های مهم برای جلوگیری از باگ‌های پنهان در پروژه‌های واقعی است.

اگر این مقاله را به‌خوبی فهمیده باشید، مهارت شما در مدیریت داده و شرط‌ها چند برابر می‌شود.

تفاوت Reference و Primitive در جاوااسکریپت

آموزش کاملاً کاربردی، از ساده تا حرفه‌ای + مثال‌های واقعی پروژه‌ای

مقدمه

یکی از مهم‌ترین و حیاتی‌ترین مفاهیمی که یک دانشجوی جاوااسکریپت باید عمیقاً یاد بگیرد، تفاوت داده‌های Primitive و Reference است.

۹۰٪ باگ‌های تازه‌کارها و حتی برنامه‌نویسان سطح متوسط، دقیقاً از همین تفاوت ایجاد می‌شود.

مثلاً چرا این کد رفتار عجیبی دارد؟

const user1 = { name: "Ali" };
const user2 = user1;

user2.name = "Sara";

console.log(user1.name); // 😱 چرا شد "Sara" ؟!

اگر جواب را دقیق نمی‌دانید، این مقاله شما را نجات می‌دهد.

در این آموزش یاد می‌گیرید:

• Primitive و Reference دقیقاً چه هستند

• در حافظه چطور ذخیره می‌شوند

• چرا تغییر یک شیء، روی دیگری اثر می‌گذارد

• چطور کپی درست بگیریم (Shallow و Deep Copy)

• مثال‌های واقعی: فرم، API، سبد خرید، UI، LocalStorage

• اشتباهات رایج و روش حرفه‌ای کار با داده‌ها

تا آخر مقاله، این موضوع را لمس می‌کنید.

بخش ۱: قبل از هر چیز، Primitive چیست؟

Primitive یعنی داده‌ای که:

• مقدار مستقیم دارد

• کوچک و سبک است

• در Stack ذخیره می‌شود

• همیشه با مقدار کپی می‌شود (BY VALUE)

Primitiveها:

• string

• number

• boolean

• undefined

• null

• symbol

• bigint

بخش ۲: Reference چیست؟

Reference یعنی داده‌ای که:

• خودش مقدار نیست

• فقط آدرس یک داده را نگه می‌دارد

• داده اصلی در Heap ذخیره می‌شود

• هنگام نسبت دادن، آدرس کپی می‌شود (BY REFERENCE)

Referenceها:

• object

• array

• function

• date

• map / set

• regex

• هر نوع ساختار پیچیده

بخش ۳: فرق از نگاه حافظه (کاملاً تصویری و قابل لمس)

Primitive در حافظه

let a = 10;
let b = a;
b = 20;

معنی واقعی:

a → 10

b → 10 (کپی مقدار)

بعد b → 20 می‌شود ولی a دست‌نخورده باقی می‌ماند.

خروجی:

a = 10
b = 20

Reference در حافظه

const obj1 = { name: "Ali" };
const obj2 = obj1; // آدرس مشترک
obj2.name = "Sara";

در حقیقت:

obj1 → [Address: X]

obj2 → [Address: X]

و شیء اصلی داخل Heap است.

پس تغییر یکی یعنی تغییر دیگری.

بخش ۴: اولین مثال واقعی (فرم ثبت‌نام)

فرض کنید داده کاربر را ذخیره می‌کنید:

const user = {
    name: "",
    age: 0
};

function register(u) {
    u.name = "Ali";
    u.age = 19;
}
register(user);

نتیجه:

user = { name: "Ali", age: 19 }

چرا؟

چون تابع به جای مقدار، آدرس شیء را دریافت کرده.

این در پروژه‌های واقعی خیلی مهم است.

بخش ۵: مشکل بزرگ Reference – وقتی فکر می‌کنید کپی گرفته‌اید ولی نگرفته‌اید

مثال اشتباه بسیار رایج:

const original = { score: 10 };
const copy = original;

copy.score = 90;

console.log(original.score); // 90 😱

دانشجویان همیشه شوکه می‌شوند.

بخش ۶: آیا آرایه‌ها هم همین رفتار را دارند؟ بله!

const list1 = [1, 2, 3];
const list2 = list1;

list2.push(4);

console.log(list1); // [1,2,3,4] 😳

این دقیقاً Reference Behavior است.

بخش ۷: Shallow Copy – کپی سطحی (تا حدی مفید)

روش‌های کپی سطحی:

۱. اسپرد (Spread)

const copy = { ...original };

۲. Object.assign

const copy = Object.assign({}, original);

۳. آرایه:

const copyArr = [...list];

اما مشکل کپی سطحی:

اگر شیء تو در تو باشد، باز هم Reference می‌ماند.

const user = {
    name: "Ali",
    address: {
        city: "Tehran"
    }
};

const copy = { ...user };
copy.address.city = "Shiraz";

console.log(user.address.city); // Shiraz 😱

بخش ۸: Deep Copy – کپی واقعی و عمیق

بهترین روش‌های ۲۰۲۶:

۱. structuredClone (جدید و عالی)

const copy = structuredClone(user);

۲. JSON روش کلاسیک

const copy = JSON.parse(JSON.stringify(user));

(محدودیت دارد ولی کاربردی است)

بخش ۹: پروژه واقعی – مدیریت سبد خرید فروشگاه

در سبد خرید، یکی از رایج‌ترین باگ‌ها:

const cart = [];
const product = { id: 1, price: 200 };

cart.push(product);

const copy = product;
copy.price = 300;

کاربر قیمت محصول را در UI دستکاری می‌کند:

cart[0].price → 300 😱

برای رفع این مشکل:

cart.push(structuredClone(product));

بخش ۱۰: پروژه واقعی – مدیریت فرم در React / Vue / Angular

اگر با Reference اشتباه رفتار کنید، کامپوننت‌ها به‌طور ناخواسته رندر می‌شوند.

کد اشتباه:

setUser(newUser); // newUser با reference به قبلی

راه‌حل:

setUser({ ...newUser });

بخش ۱۱: مثال بسیار مهم – دستکاری ناخواسته شیء در تابع

اشتباه رایج:

function updateProduct(p) {
    p.price = 900;
}

updateProduct(product); // محصول اصلی خراب شد

راه‌حل:

function updateProduct(p) {
    const copy = { ...p };
    copy.price = 900;
    return copy;
}

بخش ۱۲: Primitive ها هیچ‌وقت این مشکل را ندارند

function changeAge(age) {
    age = 100;
}

let a = 20;
changeAge(a);

console.log(a); // 20

چون Primitive → مقدار کپی می‌شود.

بخش ۱۳: مثال بزرگ‌تر – مدیریت لیست Todo

const todos = [
    { id: 1, text: "Learn JS", done: false }
];

function complete(todo) {
    todo.done = true;
}

complete(todos[0]);

مشکل: داده اصلی تغییر می‌کند.

راه‌حل حرفه‌ای:

function complete(todo) {
    return { ...todo, done: true };
}

todos[0] = complete(todos[0]);

بخش ۱۴: Reference در ساختارهای پیچیده‌تر

Map

const map = new Map();
map.set("user", { name: "Sara" });

const u = map.get("user");
u.name = "Aysan";

console.log(map.get("user").name); // Aysan

Set

const set = new Set();
const obj = { a: 1 };
set.add(obj);

const x = obj;
x.a = 99;

console.log([...set][0].a); // 99

بخش ۱۵: اشتباهات رایج دانشجوها

❌ فکر می‌کنند = یعنی کپی واقعی

❌ فکر می‌کنند Spread همیشه Deep Copy است

❌ نمی‌دانند توابع Reference را تغییر می‌دهند

❌ در JSON و LocalStorage کپی درست نمی‌گیرند

❌ در React/Vue با Reference ناخواسته UI خراب می‌کنند

بخش ۱۶: روش حرفه‌ای مدیریت Reference

✓ همیشه برای ارسال به تابع، کپی بسازید

✓ اگر داده تو در تو است → Deep Copy

✓ برای UI → همیشه Immutable رفتار کنید

✓ هرگز Reference را بدون آگاهی پاس ندهید

✓ در React/Vue حتماً از ساختارهای جدید بسازید

بخش ۱۷: تمرین پروژه‌ای – ساخت سیستم مدیریت کاربر

const user = {
    name: "Ali",
    address: {
        city: "Tehran"
    }
};

function setCity(obj, city) {
    const u = structuredClone(obj);
    u.address.city = city;
    return u;
}

const updated = setCity(user, "Shiraz");

console.log(user.address.city); // Tehran
console.log(updated.address.city); // Shiraz

این تمرین را چند بار با داده‌های مختلف تکرار کنید.

نتیجه‌گیری

در این مقاله یاد گرفتید:

• Primitive کپی مقدار است

• Reference کپی آدرس است

• Reference در پروژه‌ها خطرناک است

• کپی سطحی همیشه کافی نیست

• کپی عمیق بهترین روش برای داده‌های پیچیده است

• در پروژه‌هایی مثل فروشگاه، Todo، فرم، UI، API → Reference بسیار مهم است

اگر این را دقیق یاد گرفته باشید، پایه‌ی ذهنی شما برای ادامه‌ی مسیر جاوااسکریپت بسیار قوی می‌شود.

آموزش جامع و کاربردی Data Types در جاوااسکریپت (۲۰۲۶)

راهنمای کامل از سطح مبتدی تا حرفه‌ای برای فهم انواع داده‌ها، رفتار حافظه، تفاوت‌ها و کاربردهای واقعی

بخش ۱: مقدمه – چرا باید انواع داده‌ها را بفهمیم؟

اگر در جاوااسکریپت نتوانید انواع داده‌ها را درست بفهمید:

• نمی‌توانید داده‌ها را درست ذخیره کنید

• هنگام مقایسه باگ می‌گیرید

• در کار با APIها به خطای نوع داده می‌خورید

• تبدیل نوع داده (Type Coercion) رفتار عجیب پیدا می‌کند

• برنامه در حافظه رفتار ناخواسته دارد

• رفتار Reference و Primitive را اشتباه استفاده می‌کنید

• ساختارهای داده مثل آرایه و آبجکت را نادرست مدیریت می‌کنید

به همین دلیل Data Types یکی از بنیادی‌ترین بخش‌های یادگیری جاوااسکریپت است.

خبر خوب:

در این مقاله همه چیز را با مثال‌های واقعی و قابل لمس یاد خواهید گرفت.

بخش ۲: انواع داده‌ها در جاوااسکریپت

جاوااسکریپت دارای ۸ نوع داده اصلی است:

Primitive Types (بدون مرجع – مقدار ثابت در حافظه)

  1. string
  2. number
  3. boolean
  4. null
  5. undefined
  6. symbol
  7. bigint

Reference Types (نوع مرجع: در حافظه یک آدرس دارند)

  1. object• array• function• date• regex• map / set• …

اما قبل از ورود به جزئیات، یک تفاوت مهم:

Primitive = کپی مقدار

Reference = کپی آدرس (و این یعنی تغییرات خطرناک!)

این موضوع را در بخش‌های بعدی کاملاً لمس می‌کنید.

بخش ۳: Primitive Types – مقداری و قابل لمس

۳.۱ نوع داده string (رشته)

نمونه:

let name = "Kamran";
let message = 'Hello';
let text = `Template Literal`;

مثال‌های واقعی:

ذخیره نام کاربر:

const userName = "َAhmad Kamran";

ساخت پیام کاربر:

let greeting = `Welcome ${userName}`;

کاربرد در پروژه‌ها:

• فرم ثبت‌نام

• جستجوی محصولات

• پیام‌های خطا و هشدار

• ذخیره داده‌های دریافت شده از API

۳.۲ number (عدد)

let age = 25;
let price = 19.99;

جاوااسکریپت فقط یک نوع عدد دارد!

اعداد صحیح و اعشاری یک نوع هستند.

مثال واقعی:

محاسبه قیمت سبد خرید:

let total = 0;
total += 120000;
total += 45000;

console.log(total);

نکته مهم:

جاوااسکریپت در اعشار همیشه دقیق نیست:

0.1 + 0.2 // 0.30000000000000004

در پروژه‌ها باید از:

• کتابخانه‌ها (decimal.js)

• یا روش ضرب و تقسیم

استفاده کرد.

۳.۳ boolean (درست یا غلط)

let isLoggedIn = true;
let hasError = false;

مثال واقعی:

نمایش/عدم نمایش منو:

let isMenuOpen = false;

if (isMenuOpen) {
    console.log("Menu is open");
}

۳.۴ undefined – متغیر تعریف شده اما مقدار ندارد

let x;
console.log(x); // undefined

مثال واقعی:

یک ورودی فرم که هنوز کاربر چیزی ننوشته:

let userInput;

۳.۵ null – مقدار خالی عمدی

let selectedProduct = null;

مثال واقعی:

وقتی هیچ محصولی انتخاب نشده:

let selectedProduct = null;

وقتی کاربر یک محصول انتخاب می‌کند:

selectedProduct = { id: 1, title: "Laptop" };

۳.۶ symbol – برای کلیدهای یکتا

برای پروژه‌های پیشرفته استفاده می‌شود.

۳.۷ bigint – اعداد خیلی بزرگ

let big = 123456789012345678901234567890n;

بخش ۴: Reference Types – داده‌هایی که آدرس دارند

این بخش مهم‌ترین بخش مقاله است؛ چون رفتار Reference در جاوااسکریپت همیشه برای مبتدی‌ها گیج‌کننده است.

اما با مثال‌های واقعی خیلی ساده می‌شود.

۴.۱ object (شیء)

ساختار کلیدی–مقداری:

const user = {
    name: "Sara",
    age: 22
};

مثال واقعی:

ذخیره داده محصول:

const product = {
    id: 1,
    title: "Phone",
    price: 8900000
};

۴.۲ array (آرایه)

لیست داده‌ها:

const numbers = [1, 2, 3];

مثال واقعی:

لیست محصولات:

const cart = [
    { id: 1, title: "Laptop", price: 30_000_000 },
    { id: 2, title: "Mouse", price: 300_000 }
];

۴.۳ function (تابع)

در جاوااسکریپت تابع نوع داده است:

function sum(a, b) {
    return a + b;
}

مثال واقعی:

const showMessage = () => {
    console.log("Welcome");
};

بخش ۵: تفاوت اصلی Primitive و Reference (مهم‌ترین درس)

در Primitive رفتار این است:

let a = 10;
let b = a;

b = 20;

console.log(a); // 10
console.log(b); // 20

اما در Reference:

const obj1 = { name: "Ali" };
const obj2 = obj1;

obj2.name = "Sara";

console.log(obj1.name); // Sara 😱

چرا؟

چون:

• obj1 مقدار نیست

• obj1 آدرس حافظه است

• obj2 همان آدرس را دریافت می‌کند

نتیجه:

تغییر obj2 یعنی تغییر obj1

این یکی از رایج‌ترین باگ‌های تازه‌کارهاست.

بخش ۶: مثال واقعی Reference (لمسی!)

فرض کنید یک فرم دارید:

const user = { name: "" };

// این تابع مقدار را تغییر می‌دهد
function updateUser(obj) {
    obj.name = "Ali";
}

updateUser(user);

console.log(user.name); // Ali

چرا تغییر کرد؟

چون تابع آدرس شیء user را دریافت کرده.

بخش ۷: جلوگیری از مشکل Reference – Copy کردن شیء

کپی سطحی (Shallow Copy)

const userCopy = { ...user };

کپی عمیق (Deep Copy)

۱. روش JSON:

const deepCopy = JSON.parse(JSON.stringify(obj));

۲. روش structuredClone (استاندارد جدید):

const clone = structuredClone(obj);

بخش ۸: typeof – تشخیص نوع داده

typeof 10 // "number"
typeof "Hi" // "string"
typeof [] // "object"
typeof null // "object"  (باگ قدیمی جاوااسکریپت)

نکته مهم:

• typeof برای تشخیص array مناسب نیست

از Array.isArray() استفاده کنید.

بخش ۹: تبدیل نوع داده (Type Casting)

یکی از کاربردی‌ترین بخش‌ها در پروژه‌هاست.

۹.۱ تبدیل به number

Number("10") // 10
Number("") // 0
Number("Hi") // NaN

مثال واقعی:

let price = Number(priceInput.value);

۹.۲ تبدیل به string

String(10) // "10"

مثال واقعی:

let message = "Your total: " + total;

۹.۳ تبدیل به boolean

Boolean("") // false
Boolean("hello") // true
Boolean(0) // false
Boolean(1) // true

مثال واقعی در فرم‌ها:

let isValid = Boolean(input.value);

بخش ۱۰: Truthy و Falsy (فوق‌العاده مهم!)

Falsy values:

• 0

• “”

• null

• undefined

• false

• NaN

مثال واقعی:

if (!username) {
    alert("Please enter your username");
}

بخش ۱۱: مثال‌های واقعی از پروژه‌ها

مثال ۱: مدیریت سبد خرید

let cartTotal = 0;

function addToCart(product) {
    cartTotal += product.price;
}

addToCart({ id: 1, price: 200000 });
addToCart({ id: 2, price: 150000 });

console.log(cartTotal);

مثال ۲: ذخیره داده در LocalStorage (نوع string است!)

localStorage.setItem("user", JSON.stringify(user));

بازخوانی:

const user = JSON.parse(localStorage.getItem("user"));

مثال ۳: ساخت سیستم Todo List

const todos = [];

function addTodo(text) {
    todos.push({
        id: Date.now(),
        text,
        completed: false
    });
}

addTodo("Learn JavaScript");
console.log(todos);

در این مثال انواع داده:

• string → متن

• number → id

• boolean → وضعیت

• object → هر todo

• array → لیست todoها

بخش ۱۲: اشتباهات رایج دانشجویان

❌ اشتباه ۱: مقایسه نوع داده اشتباه

"10" == 10  // true (خطرناک!)

✔️ همیشه از === استفاده کنید

❌ اشتباه ۲: اصلاح کردن آرایه یا شیء هنگام ارسال به تابع (Mutation)

✔️ از کپی استفاده کنید

❌ اشتباه ۳: فکر کردن اینکه null و undefined یکسان‌اند

خیر!

❌ اشتباه ۴: متوجه نبودن رفتار Reference

❌ اشتباه ۵: ذخیره داده در LocalStorage بدون JSON

بخش ۱۳: تمرین عملی (مینی‌پروژه)

پروژه: سیستم مدیریت کاربر

این مثال را بنویسید، اجرا کنید و ببینید چطور انواع داده در کنار هم استفاده می‌شود:

const user = {
    name: "",
    age: null,
    hobbies: []
};

function setName(name) {
    user.name = String(name);
}

function setAge(age) {
    user.age = Number(age);
}

function addHobby(hobby) {
    user.hobbies.push(String(hobby));
}

setName("Sara");
setAge("24");
addHobby("Reading");

console.log(user);

جمع‌بندی

در این مقاله یاد گرفتید:

• انواع داده Primitive و Reference

• تفاوت رفتار آنها در حافظه

• typeof و تشخیص نوع داده

• تبدیل نوع داده – کاربردی و واقعی

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

• مثال‌های پروژه‌ای مثل API، LocalStorage، سبد خرید و Todo List

• ساختارهای داده کاربردی

اگر این مقاله را کاملاً فهمیده باشید، پایه‌ی شما در جاوااسکریپت بسیار قوی شده است.

متغیرها در جاوااسکریپت

راهنمای کامل، کاربردی و حرفه‌ای برای یادگیری متغیرها، Scope، Hoisting و تفاوت var, let, const

مقدمه

متغیرها یکی از بنیادی‌ترین مفاهیم در هر زبان برنامه‌نویسی هستند. بدون متغیرها هیچ برنامه‌ای امکان ذخیره داده، پردازش اطلاعات، تعریف ساختارهای منطقی یا تعامل با کاربر را ندارد. در جاوااسکریپت نیز متغیرها نقش کلیدی دارند و رفتار منحصر‌به‌فرد این زبان باعث می‌شود درک عمیق متغیرها برای کدنویسی حرفه‌ای ضروری باشد.

این مقاله راهنمای جامع و کامل متغیرها در جاوااسکریپت است.

در این مطلب با مثال‌های واقعی یاد می‌گیریم:

• متغیر چیست؟

• با var، let و const چه تفاوتی دارند؟

• Scope دقیقاً چگونه کار می‌کند؟

• Hoisting چیست و چرا درک آن حیاتی است؟

• چه اشتباهاتی در استفاده از متغیرها رخ می‌دهد؟

• بهترین شیوه‌ها در پروژه‌های حرفه‌ای چیست؟

و چندین سناریوی کاربردی که برنامه‌نویسان روزانه با آنها روبه‌رو می‌شوند.

بخش ۱: متغیر چیست و چرا مهم است؟

متغیر در جاوااسکریپت یک ظرف برای ذخیره داده است.

هر متغیر می‌تواند در طول زمان:

• مقدار بگیرد

• مقدارش تغییر کند

• به عنوان ورودی یا خروجی یک تابع استفاده شود

• ساختارهای پیچیده مانند آرایه یا شیء را نگه دارد

مثال ساده:

let name = "Sara";
let age = 25;
let isLoggedIn = true;

جاوااسکریپت یک زبان Dynamic Typed است یعنی:

• نوع متغیر هنگام تعریف تعیین نمی‌شود

• مقدار تعیین‌کننده نوع است

• می‌توان مقدار متغیر را در طول برنامه عوض کرد

مثال:

let x = 10;
x = "Hello"; // کاملاً معتبر است

بخش ۲: معرفی var، let و const

جاوااسکریپت سه روش برای تعریف متغیر ارائه می‌دهد:

  1. var (قدیمی – ES5 و قبل‌تر)
  2. let (جدید – ES6)
  3. const (جدید – ES6)

اما تفاوت آنها چیست؟

قبل از ورود به جزئیات، یک جدول کوتاه:

• var → اسکوپ تابعی، رفتار قدیمی، مشکلات زیاد

• let → اسکوپ بلوکی، مناسب‌ترین گزینه برای متغیرهای تغییرپذیر

• const → اسکوپ بلوکی، برای مقادیر ثابت یا ساختارهای غیرقابل تغییر

در ادامه به‌صورت کامل و با مثال بررسی می‌کنیم.

بخش ۳: var — روش قدیمی و پرعیب‌ونقص تعریف متغیر

متغیر var قبل از ES6 تنها روش تعریف متغیر بود.

اما var مشکلات جدی دارد.

مثال پایه:

var name = "Ali";
var age = 30;

مشکل ۱: Scope تابعی و عدم بلوک‌پذیری

برخلاف let و const، متغیر var به بلاک محدود نمی‌شود.

مثال:

if (true) {
    var x = 10;
}
console.log(x); // 10 — خارج از بلاک قابل دسترسی است!

این رفتار می‌تواند در پروژه‌های بزرگ باعث ایجاد باگ‌های پنهان شود.

مشکل ۲: امکان تعریف دوباره متغیر

var x = 10;
var x = 20; // بدون خطا

در پروژه‌های بزرگ این مسئله بسیار خطرناک است.

مشکل ۳: Hoisting خطرناک

var قبل از اجرا به بالای Scope منتقل می‌شود:

console.log(x);  // undefined
var x = 10;

اگرچه کد بالا خطا نمی‌دهد، اما یکی از رایج‌ترین منابع ایجاد باگ است.

به همین دلیل در استانداردهای مدرن استفاده از var تقریباً ممنوع است.

بخش ۴: let — روش استاندارد و مدرن برای تعریف متغیر

let در ES6 معرفی شد و تقریباً همیشه گزینه مناسب‌تری نسبت به var است.

مثال:

let age = 25;
age = 26;

ویژگی اصلی let:

بلوک اسکوپ (Block Scope)

if (true) {
    let y = 20;
}
console.log(y); // خطا: y is not defined

این رفتار کدنویسی را قابل پیش‌بینی‌تر و امن‌تر می‌کند.

مثال کاربردی واقعی:

در یک حلقه برای افزودن Event Listener همیشه باید از let استفاده کرد:

for (let i = 0; i < 5; i++) {
    setTimeout(() => console.log(i), 1000);
}

خروجی:

0 1 2 3 4

اما اگر var استفاده شود:

5 5 5 5 5

به همین دلیل کل جامعه جاوااسکریپت استفاده از let را توصیه می‌کند.

بخش ۵: const — برای مقادیر ثابت یا ساختارهای غیرقابل تغییر

const نیز بلوک‌اسکوپ است.

اما مهم‌ترین ویژگی آن:

مقدار متغیر const قابل تغییر نیست.

const PI = 3.14;
PI = 4; // ❌ خطا

اما نکته بسیار مهم:

const ساختار را قفل نمی‌کند؛ فقط reference ثابت می‌ماند!

مثال:

const user = { name: "Ali" };
user.name = "Sara"; // ✔️ معتبر

اما:

user = {}; // ❌ خطا

مثال کاربردی: تعریف تنظیمات برنامه

const CONFIG = {
    apiUrl: "/api",
    timeout: 3000
};

در پروژه‌های بزرگ بیشتر مقادیر ثابت را با const تعریف می‌کنند.

بخش ۶: مقایسه کامل var، let، const

1. Scope

• var → تابعی

• let → بلوکی

• const → بلوکی

2. قابلیت تغییر مقدار

• var → قابل تغییر

• let → قابل تغییر

• const → غیرقابل تغییر (reference ثابت)

3. Hoisting

• var → بالا می‌رود ولی مقدار ندارد

• let و const → بالا می‌روند اما در TDZ قرار می‌گیرند (خطا می‌دهند)

4. قابلیت تعریف دوباره

• var → بله

• let → خیر (خطا)

• const → خیر (خطا)

انتخاب حرفه‌ای:

• برای متغیرهایی که مقدارشان تغییر نمی‌کند: const

• برای متغیرهای تغییرپذیر: let

• هرگز از var استفاده نکنید مگر برای سازگاری قدیمی

بخش ۷: Hoisting — از مهم‌ترین مفاهیم متغیرها

Hoisting یعنی:

• جاوااسکریپت متغیرها و توابع را قبل از اجرای کد بالا می‌کشد.

رفتار var:

console.log(a); // undefined
var a = 5;

رفتار let و const:

console.log(b); // ❌ خطا: Cannot access before initialization
let b = 20;

این حالت به نام TDZ (Temporal Dead Zone) شناخته می‌شود.

بخش ۸: انواع Scope در جاوااسکریپت

جاوااسکریپت سه نوع Scope دارد:

  1. Global Scope
  2. Function Scope
  3. Block Scope

۱. Global Scope

متغیرهای تعریف شده بیرون از همه بلوک‌ها:

let site = "Example.com";

به همه جا دسترسی دارند (حتی داخل توابع).

۲. Function Scope

متغیر var فقط تابع‌اسکوپ است:

function test() {
    var x = 10;
}
console.log(x); // خطا

۳. Block Scope

let و const بلوک‌اسکوپ هستند:

if (true) {
    let a = 5;
}
console.log(a); // خطا

بخش ۹: Shadowing — سایه انداختن متغیرها

اگر متغیری داخل یک Scope با نام متغیر بیرونی تعریف شود، متغیر داخلی “بر روی” بیرونی سایه می‌اندازد.

مثال:

let x = 10;

function test() {
    let x = 20;
    console.log(x); // 20
}

test();
console.log(x); // 10

بخش ۱۰: تفاوت major بین let و const در پروژه‌های واقعی

let برای “وضعیت‌های متغیر”:

• شمارنده‌ها

• محتویات فرم

• وضعیت UI (toggle، open/close)

• داده‌های قابل تغییر

let isOpen = false;
isOpen = true;

const برای موارد ثابت:

• تنظیمات

• انتخاب المان‌ها از DOM

• ساختارهای ثابت

const button = document.querySelector("button");

در پروژه‌های مدرن تقریباً:

• 70٪ متغیرها → const

• 30٪ → let

بخش یازدهم: قوانین نام‌گذاری متغیرها (Best Practices)

مجاز نیستند:

• شروع با عدد

• استفاده از فاصله

• کاراکترهای خاص مثل ! % / \

قوانین صحیح:

• استفاده از camelCase

• نام معنی‌دار

• پرهیز از یک‌حرفی بودن (به‌جز مواردی مثل i در حلقه)

مثال خوب:

let totalPrice = 1500;
let userName = "Sara";
let isLoggedIn = true;

بخش دوازدهم: انواع مقداردهی و تعریف متغیر

۱. تعریف همراه مقدار:

let a = 10;

۲. تعریف بدون مقدار:

let b;
console.log(b); // undefined

۳. مقداردهی مجدد:

let c = 5;
c = 12;

۴. تعریف چند متغیر:

let x = 1, y = 2, z = 3;

بخش سیزدهم: بهترین شیوه‌ها (Best Practices)

• همیشه از const استفاده کنید مگر اینکه نیاز به تغییر مقدار باشد

• هرگز var استفاده نکنید

• متغیرها را در بالاترین محدوده لازم تعریف کنید

• نام‌های واضح انتخاب کنید

• از تعریف متغیرهای بدون مقدار پرهیز کنید مگر ضروری باشد

• در اسکوپ‌های کوچک از let/const استفاده کنید

• از تغییر بی‌دلیل نوع داده پرهیز کنید

بخش چهاردهم: سناریوهای واقعی استفاده از متغیرها

سناریو ۱: مدیریت سبد خرید

let cartTotal = 0;

function addToCart(price) {
    cartTotal += price;
}

addToCart(100);
addToCart(50);
console.log(cartTotal); // 150

سناریو ۲: ذخیره وضعیت UI

let isSidebarOpen = false;

toggleBtn.addEventListener("click", () => {
    isSidebarOpen = !isSidebarOpen;
});

سناریو ۳: استفاده از const برای DOM

const modal = document.getElementById("modal");
modal.style.display = "block";

سناریو ۴: تسک‌های API

const API_URL = "/api/products";

بخش پانزدهم: اشتباهات رایج درباره متغیرها

❌ ۱. استفاده از var

❌ ۲. استفاده از نام‌های بی‌معنی

❌ ۳. تعریف متغیرهایی که فقط در یک خط استفاده می‌شوند

❌ ۴. تغییر نوع متغیر بدون دلیل

❌ ۵. ناآگاهی از Scope و Hoisting

جمع‌بندی نهایی

متغیرها قلب برنامه‌نویسی جاوااسکریپت هستند.

در این مقاله یاد گرفتیم که:

• var قدیمی و پرخطر است

• let برای مقادیر تغییرپذیر عالی است

• const برای مقادیر ثابت یا references است

• let و const بلوک‌اسکوپ هستند

• var تابع‌اسکوپ است

• Hoisting برای var متفاوت و خطرناک است

• برای انتخاب متغیر باید اصول Best Practice رعایت شود

درک درست متغیرها باعث می‌شود:

• کدهای حرفه‌ای‌تر بنویسید

• باگ‌های کمتر داشته باشید

• ساختار پروژه شفاف‌تر باشد

• رفتار کد قابل‌پیش‌بینی‌تر شود