همونطور که اطلاع دارید در جلسه قبل مقدماتی در مورد Symbol ها قرار دادیم و شما رو با اون آشنا کردیم. در این جلسه میخوایم این موضوع رو ادامه بدیم و مباحث مربوط به Symbolها رو به پایان برسونیم.
استفاده از Symbol بعنوان کلید شئ
در جلسه قبل یک مثال در مورد کاربرد سمبلها زدیم و از اونا در مقدار دهی ثابتها استفاده کردیم. در این جلسه میخوایم یک کاربرد متداول دیگر از سمبلها رو بهتون آموزش بدیم. از سمبلها بعنوان کلید اشیاء نیز بصورت متداول استفاده میشه. همونطور که اطلاع دارید میتونیم با استفاده از [] یک رشته رو به عنوان کلید یک شئ قرار بدیم. کد زیر رو در نظر بگیرید:
let data = {}; data['name'] = 'Ted Mosby'; data['nickname'] = 'Teddy Westside'; data['city'] = 'New York';
همونطور که میبینید یک شئ رو در خط 1 به وجود آوردیم و در خط 2 تا 4، سه کلید رو برای اون قرار دادیم و اونا رو مقداردهی کردیم. با استفاده از [] میتونیم Symbolها رو نیز به عنوان کلید اشیاء قرار بدیم. اینکار چند مزیت داره:
- اطمینان حاصل میکنید که کلیدهای بر پایه سمبل، با هم تداخل ایجاد نمیکنند (چون یکتا هستند). برخلاف رشتهها که امکان داره با ویژگی و متدهای دیگه تداخل داشته باشند.
- کلیدهای بر پایه سمبل، در اکثر مواقع شمرده نمیشن و از اونا صرف نظر میشه. مثلا در حلقه و توابعی همچون و و از اونا صرف نظر میشه و مثل این میمونه که اصلا وجود ندارند. پس مواقعی که میخواید یک کلید در Serialize شدن شئ وجود نداشته باشد، میتونین از سمبلها استفاده کنید.
کد زیر رو در نظر بگیرید:
let user = {}; let email = Symbol(); user.name = 'Fred'; user.age = 30; user= '[email protected]'; Object.keys(user); // Array [ "name", "age" ] Object.getOwnPropertyNames(user); // Array [ "name", "age" ] JSON.stringify(user); // "{"name":"Fred","age":30}"
همونطور که میبینید در خط اول یک شئ بنام user تعریف کردیم. در خط 2 یک Symbol تعریف کردیم و اون رو درون متغیر email قرار دادیم. در خط 6 این سمبل ساخته شده رو بعنوان کلید شئ user قرار دادیم و یک ایمیل رو برای مقدار اون قرار دادیم. در خطوط 8 و 10 و 12 متدهای بیان شده رو مورد استفاده قرار دادیم. همونطور که در خروجی هر کدام میبینید، هیچ اثری از کلید email که بر پایه سمبل هست وجود ندارد.
نحوه دسترسی به کلیدهای از نوع Symbol
همونطور که دیدید با استفاده از توابع عادی نمیتونین به کلیدهای بر پایه سمبل دسترسی پیدا کنید. برای دسترسی به این موارد میتونین از دو روش زیر استفاده کنید. کد زیر رو در نظر بگیرید:
let user = {}; let email = Symbol(); user.name = 'Fred'; user.age = 30; user= '[email protected]'; Object.getOwnPropertySymbols(user); // Array [ Symbol() ] Reflect.ownKeys(user); // Array [ "name", "age", Symbol() ]
همونطور که میبینید در خط 8 از متد
استفاده کردیم. با استفاده از این متد، آرایه ای از کلیدهای بر پایه سمبل برگشت داده میشه و از بقیه کلیدها صرف نظر میشه. در خط 10 از Reflect API (اضافه شده در ES6) استفاده کردیم و با بهره بردن از متد میتونیم به همه کلیدهای یک شئ (چه سمبلی چه غیر سمبلی) دسترسی داشته باشیم.سمبلهای شناخته شده یا Well-Known
همونطور که دیدید با استفاده از ES5 هیچ راهی برای دسترسی به کلیدهایی که بر پایه سمبلها هستند، وجود ندارد و در حقیقت اگر اونا رو در ES6 اضافه کنیم، هیچ تاثیری در ES5 نخواهد داشت. در ES6 از این قابلیت استفاده شده است و امکانات و ویژگیهای جدیدی به Javascript اضافه شده که Backward Compatible (سازگار با نسخههای قدیمی) هستند و هیچ اختلالی در مرورگرهای قدیمی که از ES6 پشتیبانی نمیکنند، به وجود نمیآورند. منظور از اصطلاح Well-Known یا شناخته شده، اون سمبل هایی هستند که از پیش تعریف شده میباشند و هدف اونا افزودن ویژگیهای خاصی به زبان هسته javascript است. یکی از امکانات اضافه شده با استفاده از این روش، iteratorها هستند.
مثلا Symbol.iterator یک سمبل شناخته شده است که با استفاده از اون میتونیم به همه المنتهای یک شئ یا آرایه یا ... دسترسی داشته باشیم. کد زیر رو در نظر بگیرید:
let band = ['Freddy', 'Brian', 'John', 'Roger']; let iterator = band[Symbol.iterator](); console.log(iterator.next().value); // { value: "Freddy", done: false } console.log(iterator.next().value); // { value: "Brian", done: false } console.log(iterator.next().value); // { value: "John", done: false } console.log(iterator.next().value); // { value: "Roger", done: false } console.log(iterator.next().value); // { value: undefined, done: true }
همونطور که دیدید یک آرایه رو تعریف کردیم و یک متد با نام Symbol.iterator رو به اون اضافه کردیم. با اینکار میتونیم با استفاده از متد next به همه اعضای آرایه دسترسی داشته باشیم و value رو در Console چاپ کنیم.
انواع آرایه، رشته، TypedArray (اضافه شده در ES6) و Map و Set دارای یک متد از پیش تعریف شده Symbol.iterator هست و زمانی که این انواع رو در حلقه لینک مراجعه کنید و یا در Console عبارت Symbol.prototype رو تایپ کنید:
همونطور که میبینید سمبلهای شناخته شده در اینجا قرار داده شده اند. هر کدام از این موارد ویژگیهای خاصی رو به بخشی از زبان Javascript افزوده است که میتونین از اون بهره ببرید یا اون رو متناسب با سلیقه خودتون تغییر بدین.
مطالعه بیشتر
برای مطالعه بیشتر در زمینه سمبلها میتونین لینکهای زیر رو مطالعه بفرمایید:
امیدوارم تونسته باشم این نوع Primitive جدید رو بصورت مقدماتی به شما آموزش داده باشم.
موفق و پیروز باشید.
یا علی
فقط میتونم بگم ایولا که داری چیزهای به روز یاد میدی
خوشحالم که بدردتون خورده
موفق باشید