مقدمه

در درس قبلی با تکنیک Optional Chaining برای دسترسی امن به پراپرتی‌های تو در تو آشنا شدیم. حالا نوبت آشنایی با نوع داده‌ای است که نسبت به همه نوع‌های اولیه دیگر کاملاً منحصربه‌فرد است: Symbol. نوع Symbol اولین بار در ES6 معرفی شد تا به کمک آن بتوانید پراپرتی‌های یکتا و غیرقابل تداخل در اشیاء تعریف کنید و از بسیاری از مشکلات مربوط به تداخل کلیدهای پراپرتی‌ها خلاص شوید.

Symbol در جاوااسکریپت

Symbol یک نوع داده اولیه است که برای ایجاد کلیدهای یکتا و غیرتکراری استفاده می‌شود. برخلاف string، هر بار که یک Symbol جدید می‌سازید — حتی اگر توضیح (description) یکسانی داشته باشد — آن Symbol کاملاً منحصر به فرد است.

برای ساخت Symbol کافی است تابع Symbol() را فراخوانی کنید. می‌توانید به دلخواه یک توضیح برای خوانایی بیشتر به آن بدهید (که فقط جنبه توصیفی دارد):

Copy Icon JAVASCRIPT
let id = Symbol();
let sym = Symbol("userId");
console.log(sym); // Symbol(userId)

تاکید می‌کنم حتی اگر دو Symbol با توضیح یکسان بسازید، باز هم این دو کاملاً مستقل و یکتا هستند.

استفاده از Symbol به عنوان کلید پراپرتی

مهم‌ترین کاربرد Symbol، استفاده از آن به عنوان کلید پراپرتی شیء است. پراپرتی‌هایی که با Symbol ساخته می‌شوند، هیچ تداخلی با پراپرتی‌های معمول (string) ندارند و حتی در حلقه for...in و متد Object.keys() نمایش داده نمی‌شوند. بنابراین، به ترتیبی که در کد زیر می‌بینید، می‌توانید پراپرتی‌هایی بسازید که فقط با داشتن خود Symbol قابل دسترسی‌اند و با پراپرتی‌های دیگر تداخلی ندارند.

Copy Icon JAVASCRIPT
let id = Symbol("id");
let user = {
  name: "Ali",
  [id]: 12345
};
console.log(user[id]); // 12345

for (let key in user) {
  console.log(key); // name 
}
console.log(Object.keys(user)); // ['name']

در این مثال، پراپرتی id که با Symbol ساخته شده، فقط با خود Symbol قابل دسترسی است و در حلقه for...in یا متد Object.keys() نمایش داده نمی‌شود.

تفاوت Symbol و string به عنوان کلید

اگر پراپرتی‌ها را با string تعریف کنید، احتمال تداخل و بازنویسی کلید وجود دارد. اما Symbol تضمین می‌کند که هر کلید واقعاً یکتا و غیرقابل تکرار است. مثال زیر را ببینید.

Copy Icon JAVASCRIPT
let id1 = Symbol("id");
let id2 = Symbol("id");
console.log(id1 === id2); // false

let obj = {};
obj[id1] = "first";
obj[id2] = "second";
console.log(obj[id1]); // "first"
console.log(obj[id2]); // "second"

همان‌طور که می‌بینید، دو Symbol با توضیح یکسان، پراپرتی‌های کاملاً مجزایی تولید می‌کنند.

کاربردهای پیشرفته Symbol

جاوااسکریپت علاوه بر Symbolهای معمولی، مجموعه‌ای Symbol داخلی (مثل Symbol.iterator و Symbol.toPrimitive) دارد که امکان سفارشی‌سازی رفتار اشیاء را فراهم می‌کند. مثلاً اگر بخواهید شیءتان را قابل استفاده در حلقه for...of یا تبدیل به مقدار اولیه کنید، می‌توانید این Symbolها را در شیء خود تعریف کنید. این موضوع در فصل‌های پیشرفته‌تر آموزش داده خواهد شد.

پس، نوع داده Symbol ابزاری مدرن و قدرتمند برای ایجاد کلیدهای یکتا و پنهان در اشیاء جاوااسکریپت است. استفاده از Symbol از بسیاری از مشکلات مربوط به تداخل پراپرتی‌ها جلوگیری می‌کند و راه‌حلی حرفه‌ای برای طراحی ساختارهای داده‌ای امن و توسعه‌پذیر به شما می‌دهد.

در درس بعد با مفهوم تبدیل اشیاء به مقدار اولیه (Object to Primitive) و روش‌های کنترل این رفتار آشنا می‌شویم.