برنامه نویسی و ITجاوا اسکریپت

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

Symbol در جاوا اسکریپت تابعی است که برای شناسایی ویژگی‌های شی‌ء استفاده می‌شود. در این پست آموزشی از مکتب خونه آموزش با نوع اولیه سیمبل یا نماد در جاوا اسکریپت و نحوه استفاده مؤثر از نماد آشنا خواهیم شد.

نکاتی که قبل از شروع آموزش باید به خاطر بسپاریم:

  • یک متد Symbol همیشه یک مقدار منحصربه‌فرد را برمی‌گرداند.
  • یک مقدار Symbol ممکن است به‌عنوان یک شناسه برای ویژگی‌های شی‌ء استفاده شود.
  • Symbol ها مانند اعداد یا رشته‌ها تغییرناپذیر هستند.
  • Symbol ها را نمی‌توان به انواع داده‌های اولیه تایپ کرد.
ویدئو پیشنهادی: جاوا اسکریپت

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

ES6 سیمبل را به‌عنوان یک نوع بدوی جدید به جاوا اسکریپت اضافه کرد. برخلاف سایر انواع داده‌های اولیه مانند عدد، بولی، تهی، تعریف‌نشده و رشته، نوع Symbol در جاوا اسکریپت شکل تحت‌اللفظی ندارد.

برای ایجاد یک سیمبل جدید، از تابع سراسری Symbol همان‌طور که در این مثال نشان داده‌شده است استفاده می‌کنیم. درواقع سینتکس آن به‌صورت زیر است:

Symbol([description])

مثال:

let s = Symbol('foo');

تابع Symbol هر بار که آن را فراخوانی می‌کنید یک مقدار منحصربه‌فرد جدید ایجاد می‌کند:

console.log(Symbol() === Symbol()); // false

تابع Symbol یک توضیح (description) را به‌عنوان یک آرگومان اختیاری می‌پذیرد. این توصیف نماد شمارا توصیفی‌تر می‌کند.

مثال زیر دو علامت ایجاد می‌کند: firstName و lastName.

let firstName = Symbol('first name'),
    lastName = Symbol('last name');

با استفاده از متد toString می‌توانید به ویژگی توضیحات Symbol دسترسی پیدا کنید. متد console.log متد toString سیمبل یا نماد را به‌طور ضمنی همان‌طور که در مثال زیر نشان داده‌شده است فراخوانی می‌کند:

console.log(firstName); // Symbol(first name)
console.log(lastName); // Symbol(last name)

ازآنجایی‌که Symbol ها مقادیر اولیه هستند، می‌توانید از عملگر typeof برای بررسی اینکه آیا یک متغیر نماد است یا خیر استفاده کنید. ES6 نوع توسعه‌یافته‌ای را برای برگرداندن رشته Symbol هنگامی‌که متغیر نماد را ارسال می‌کنید، گسترش داد.

console.log(typeof firstName); // symbol

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

let s = new Symbol(); // error

به اشتراک‌گذاری Symbol در جاوا اسکریپت

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

متد Symbol.for یک پارامتر واحد را می‌پذیرد که می‌تواند برای توصیف نماد استفاده شود، همان‌طور که در مثال زیر نشان داده‌شده است:

let ssn = Symbol.for('ssn');

متد Symbol.for ابتدا نماد را با کلید ssn در رجیستری Symbol جهانی جستجو می‌کند. در صورت وجود Symbol موجود را برمی‌گرداند. در غیر این صورت، متد Symbol.for یک سیمبل جدید ایجاد می‌کند، آن را با کلید مشخص‌شده در رجیستری نماد جهانی ثبت می‌کند و نماد را برمی‌گرداند.

بعداً، اگر متد Symbol.for را با استفاده از همان کلید فراخوانی کنید، متد Symbol.for نماد موجود را برمی‌گرداند.

let citizenID = Symbol.for('ssn');
console.log(ssn === citizenID); // true

در این مثال از متد Symbol.for برای جستجوی Symbol در جاوا اسکریپت با کلید ssn استفاده کردیم. ازآنجایی‌که رجیستری Symbol جهانی قبلاً حاوی آن بود، متد Symbol.for آن را برگرداند.

برای دریافت کلید مرتبط با یک Symbol، از متد Symbol.keyFor همان‌طور که در مثال زیر نشان داده‌شده است استفاده می‌کنید:

console.log(Symbol.keyFor(citizenID)); // 'ssn'

اگر Symbol در رجیستری نماد جهانی وجود نداشته باشد، متد System.keyFor تعریف‌نشده برمی‌گرداند.

let systemID = Symbol('sys');
console.log(Symbol.keyFor(systemID)); // undefined

موارد استفاده از Symbol

Symbol در جاوا اسکریپت کاربردهای فراوانی دارد که در ادامه با این کاربرها آشنا خواهیم شد:

الف) استفاده از Symbol به‌عنوان مقادیر منحصربه‌فرد

هر زمان که از یک‌رشته یا یک عدد در کد خود استفاده می‌کنید، باید به‌جای آن از Symbol استفاده کنید. به‌عنوان‌مثال، شما باید وضعیت را در برنامه مدیریت وظایف مدیریت کنید. قبل از ES6، از رشته‌ها در حال پیشرفت، تکمیل، لغو شده و در انتظار برای نمایش وضعیت‌های مختلف یک کار استفاده می‌کردید. در ES6 می‌توانید از نمادهای زیر استفاده کنید:

let statuses = {
    OPEN: Symbol('Open'),
    IN_PROGRESS: Symbol('In progress'),
    COMPLETED: Symbol('Completed'),
    HOLD: Symbol('On hold'),
    CANCELED: Symbol('Canceled')
};
// complete a task
task.setStatus(statuses.COMPLETED);

ب) استفاده از Symbol به‌عنوان نام ویژگی محاسبه‌شده یک شی‌ء

شما می‌توانید از Symbol در جاوا اسکریپت به‌عنوان نام خصوصیات محاسبه‌شده استفاده کنید. مثال زیر را ببینید:

let status = Symbol('status');
let task = {
    [status]: statuses.OPEN,
    description: 'Learn ES6 Symbol'
};
console.log(task);

برای به دست آوردن تمام خصوصیات قابل‌شمارش یک شی‌ء، از متد Object.keys استفاده می‌کنید.

console.log(Object.keys(task)); // ["description"]

برای به دست آوردن تمام خصوصیات یک شی‌ء، خواه ویژگی‌ها قابل‌شمارش باشند یا نباشند، از متد Object.getOwnPropertyNames استفاده می‌کنید.

console.log(Object.getOwnPropertyNames(task)); // ["description"]

برای دریافت تمام  Symbolهای ویژگی یک شی‌ء، از متد Object.getOwnPropertySymbols استفاده می‌کنید که در ES6 اضافه‌شده است.

console.log(Object.getOwnPropertySymbols(task)); //[Symbol(status)]

متد Object.getOwnPropertySymbolsآرایه‌ای از سیمبل های ویژگی خود را از یک شی‌ء برمی‌گرداند.

معروفترین Symbol در جاوا اسکریپت

ES6 سیمبل هایی از پیش تعریف‌شده‌ای را ارائه می‌دهد که به آن‌ها Symbol های شناخته‌شده می‌گویند. Symbol های شناخته‌شده نشان‌دهنده رفتارهای رایج در جاوا اسکریپت هستند. هر Symbol در جاوا اسکریپت نشان‌دهنده یک ویژگی ثابتشی است.

Symbol.hasInstance

Symbol.hasInstance سیمبلی است که رفتار عملگر instanceof را تغییر می‌دهد. به‌طورمعمول، هنگامی‌که از عملگر instanceof استفاده می‌کنید:

obj instanceof type;

جاوا اسکریپت متد Symbol.hasIntance را به‌صورت زیر فراخوانی می‌کند:

type[Symbol.hasInstance](obj);

سپس به روشی بستگی دارد که تعیین کند آیا obj نمونه‌ای از شی‌ء نوع است یا خیر. مثال زیر را ببینید.

class Stack {
}
console.log([] instanceof Stack); // false

آرایه [] نمونه‌ای از کلاس Stack نیست، بنابراین عملگر instanceof در این مثال false را برمی‌گرداند. با فرض اینکه می‌خواهید آرایه [] نمونه‌ای از کلاس Stack باشد، می‌توانید متد Symbol.hasInstance را به‌صورت زیر اضافه کنید:

class Stack {
    static [Symbol.hasInstance](obj) {
        return Array.isArray(obj);
    }
}
console.log([] instanceof Stack); // true

سیمبل Symbol.iterator در جاوا اسکریپت

Symbol.iterator مشخص می‌کند که آیا یک تابع یک تکرارکننده برای یک شی‌ء برمی‌گرداند یا خیر.

  • اشیایی که دارای خاصیت iterator هستند، اشیاء تکرارپذیر نامیده می‌شوند.
  • در ES6، تمام اشیاء مجموعه (Array، Set و Map) و رشته‌ها، اشیاء قابل تکرار هستند.
  • ES6 حلقه for…of را ارائه می‌دهد که با شی‌ء تکرارپذیر مانند مثال زیر کار می‌کند.
var numbers = [1, 2, 3];
for (let num of numbers) {
    console.log(num);
}

کاربرد سیمبل در جاوا اسکریپت چیست

در داخل، موتور جاوا اسکریپت ابتدا متد Symbol.iterator آرایه اعداد را فراخوانی می‌کند تا آبجکت تکرارکننده را به دست آورد. سپس، متد iterator.next را فراخوانی می‌کند و خاصیت مقدار برای شی‌ء iterator را در متغیر num کپی می‌کند. پس از سه بار تکرار، خاصیت done شیء نتیجه درست است،  پس حلقه خارج می‌شود.

شما می‌توانید از طریق System.iterator به‌صورت زیر به شی‌ء تکرارکننده پیش‌فرض دسترسی داشته باشید:


var iterator = numbers[Symbol.iterator]();
console.log(iterator.next()); // Object {value: 1, done: false}
console.log(iterator.next()); // Object {value: 2, done: false}
console.log(iterator.next()); // Object {value: 3, done: false}
console.log(iterator.next()); // Object {value: undefined, done: true}

به‌طور پیش‌فرض، یک مجموعه قابل تکرار نیست. بااین‌حال، همان‌طور که در مثال زیر نشان داده‌شده است، می‌توانید با استفاده از Symbol.iterator آن را قابل تکرار کنید:


class List {
    constructor() {
        this.elements = [];
    }
add(element) {
this.elements.push(element);
return this;
}
*[Symbol.iterator]() {
for (let element of this.elements) {
yield element;
}
}
let chars = new List();
chars.add('A')
.add('B')
.add('C');
// because of the Symbol.iterator
for (let c of chars) {
console.log(c);
}

خروجی قطعه کد بلا:

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

Symbol.isConcatSpreadable

برای به هم پیوستن دو آرایه، از متد  concatهمانطور که در مثال زیر نشان داده‌شده است استفاده می‌کنید:


let odd  = [1, 3],
    even = [2, 4];
let all = odd.concat(even);
console.log(all); // [1, 3, 2, 4]

خروجی:

نماد در جاوا اسکریپت

در این مثال، آرایه به‌دست‌آمده شامل عناصر واحد هر دو آرایه است. علاوه بر این، متد concat نیز آرگومان غیر آرایه‌ای را می‌پذیرد که در زیر نشان داده‌شده است.

let extras = all.concat(5);
console.log(extras); // [1, 3, 2, 4, 5]

عدد 5 به عنصر پنجم آرایه تبدیل می‌شود.
همان‌طور که در مثال بالا مشاهده می‌کنید، زمانی که یک آرایه را به متد concat ارسال می‌کنیم، متد concat آرایه را در عناصر جداگانه پخش می‌کند. بااین‌حال، با یک استدلال ابتدایی متفاوت رفتار می‌کند. قبل از ES6، نمی‌توانستید این رفتار را تغییر دهید. به همین دلیل است که سیمبل Symbol.isConcatSpreadable وارد بازی می‌شود.
ویژگی Symbol.isConcatSpreadable یک مقدار بولی است که تعیین می‌کند آیا یک شی‌ء به‌صورت جداگانه به نتیجه تابع concat اضافه می‌شود.
به مثال زیر توجه کنید:

let list = {
    0: 'JavaScript',
    1: 'Symbol',
    length: 2
};
let message = ['Learning'].concat(list);
console.log(message); // ["Learning", Object]

شی‌ء فهرست به آرایه [‘Learning’] پیوسته است. بااین‌حال، عناصر فردی آن پخش نشده است.

خروجی به صورت زیر است:

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

برای فعال کردن عناصر شی‌ء list که به‌صورت جداگانه به آرایه اضافه می‌شوند هنگام انتقال به متد concat، باید ویژگی Symbol.isConcatSpreadable را به شرح زیر به شی‌ء لیست اضافه کنید:

let list = {
    0: 'JavaScript',
    1: 'Symbol',
    length: 2,
    [Symbol.isConcatSpreadable]: true
};
let message = ['Learning'].concat(list);
console.log(message); // ["Learning", "JavaScript", "Symbol"]

توجه داشته باشید که اگر مقدار Symbol.isConcatSpreadable را روی false قرار دهید و شی‌ء لیست را به متد concat ارسال کنید، به‌عنوان کل شی‌ء به آرایه الحاق می‌شود.

نتیجه اجرای قطعه کد بالا:

موارد استفاده از Symbol در جاوا اسکریپت

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

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

روش Symbol.toPrimitive تعیین می‌کند که وقتی یک شی‌ء به یک مقدار اولیه تبدیل می‌شود چه اتفاقی باید بیفتد. موتور جاوا اسکریپت روش Symbol.toPrimitive را بر روی نمونه اولیه هر نوع استاندارد تعریف می‌کند.
متد Symbol.toPrimitive یک آرگومان hint می‌گیرد که یکی از سه مقدار “number”، “string” و “default” را دارد. آرگومان hint نوع مقدار بازگشتی را مشخص می‌کند. پارامتر hint توسط موتور جاوا اسکریپت بر اساس زمینه‌ای که شی‌ء در آن استفاده می‌شود پر می‌شود. مثالی از استفاده از Symbol در جاوا اسکریپت (سیمبل Symbol.toPrimitive) آورده شده است.


function Money(amount, currency) {
    this.amount = amount;
    this.currency = currency;
}
Money.prototype[Symbol.toPrimitive] = function(hint) {
    var result;
    switch (hint) {
        case 'string':
            result = this.amount + this.currency;
            break;
        case 'number':
            result = this.amount;
            break;
        case 'default':
            result = this.amount + this.currency;
            break;
    }
    return result;
}
var price = new Money(799, 'USD');
console.log('Price is ' + price); // Price is 799USD
console.log(+price + 1); // 800
console.log(String(price)); // 799USD

خروجی قطعه کد بالا به صورت زیر خواهد بود:

نحوه استفاده از Symbol در جاوا اسکریپت

نتیجه‌گیری

در این آموزش با  symbol در جاوا اسکریپت و نحوه استفاده از آن‌ها برای مقادیر منحصربه‌فرد و ویژگی‌های شی‌ء آشنا شده‌اید. همچنین، یاد گرفتید که چگونه از symbol های شناخته‌شده برای اصلاح رفتار شی‌ء استفاده کنید.

https://www.javatpoint.com/javascript-symbol

https://www.javascripttutorial.net/es6/symbol/

کامل بهرامی

کامل بهرامی- کارشناسی ارشد مهندسی کامپیوتر، فعال در حوزه تولید محتوای برنامه نویسی، سئو و سایر حوزه های مرتبط

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا