نمادها یک بدوی نسبتاً جدید هستند که در ES6 معرفی شده اند. نماد اولیه یک مقدار منحصر به فرد را نشان می دهد که هرگز با هیچ ارزش دیگری از جمله مقادیر سایر نمادهای اولیه برخورد نمی کند. دو رشته ابتدایی متشکل از کاراکترهای یکسان کاملاً برابر ارزیابی می شوند:
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
با این حال، هیچ دو نمادی که با استفاده از Symbol()
ایجاد شده اند، هرگز نمی توانند کاملاً برابر باشند:
Symbol() === Symbol()
> false
این ویژگی به شما امکان می دهد از نمادها به عنوان کلیدهای ویژگی منحصر به فرد در یک شی استفاده کنید و از برخورد با کلیدها جلوگیری کنید که هر کد دیگری ممکن است به آن شی اضافه کند.
const mySymbol = Symbol( "Desc" );
const myObject = {
}
myObject
> Object { Symbol("Desc"): "propSymbol" }
سه نوع نماد وجود دارد:
- نمادهای ایجاد شده با
Symbol()
- نمادهای مشترکی که با استفاده از
Symbol.for()
از یک رجیستری جهانی Symbol تنظیم و بازیابی می شوند. - "نمادهای شناخته شده" به عنوان ویژگی های ثابت در شی Symbol تعریف می شوند. این نمادها حاوی روشهای داخلی هستند که نمیتوان بهطور تصادفی آنها را بازنویسی کرد.
Symbol()
یک توصیف (یا "نام نماد") را به عنوان یک آرگومان اختیاری می پذیرد. این توضیحات برچسبهای قابل خواندن توسط انسان برای اهداف اشکالزدایی هستند و بر منحصر به فرد بودن نتیجه تأثیری نمیگذارند. هر فراخوانی به Symbol
یک نماد کاملاً منحصربفرد اولیه را برمیگرداند، حتی اگر چندین تماس دارای توضیحات یکسان باشند:
Symbol( "My symbol." ) === Symbol( "My symbol." );
> false
مانند سایر انواع داده های اولیه، نمادها روش ها و ویژگی ها را از نمونه اولیه خود به ارث می برند. به عنوان مثال، می توانید به یک توضیحات به عنوان ویژگی ارثی نماد ایجاد شده دسترسی داشته باشید:
let mySymbol = Symbol( "My symbol." );
mySymbol.description
> "My symbol."
اما شما نمی توانید با استفاده از کلمه کلیدی new
یک نماد ایجاد کنید:
let mySymbol = new Symbol();
> Uncaught TypeError: Symbol is not a constructor
نمادها قابل شمارش نیستند، به این معنی که ویژگیهای نمادین هنگام استفاده از روشهای استاندارد برای تکرار روی آنها در دسترس نیستند. متد getOwnPropertySymbols()
به ویژگی های نماد یک شی دسترسی می دهد.
نمادهای مشترک
متد Symbol.for()
سعی می کند هر نماد موجود را در یک رجیستری نماد جهانی در طول زمان اجرا با یک رشته معین به عنوان کلید جستجو کند و در صورت یافتن نماد منطبق را برمی گرداند. اگر یکی را پیدا نکرد، یک نماد با کلید مشخص شده ایجاد می کند و آن را به رجیستری جهانی اضافه می کند:
let sharedSymbol = Symbol.for( "My key." );
sharedSymbol === Symbol.for( "My key." )
> true
این کلیدها هیچ همپوشانی عملکردی با توضیحات اختصاص داده شده به Symbol
اولیه ایجاد شده توسط نویسنده ندارند. برای دسترسی به یک نماد در رجیستری نماد، ابتدا باید آن را با استفاده for()
ایجاد کنید:
Symbol( "String" ) === Symbol( "String" );
> false
Symbol( "String" ) === Symbol().for( "String" );
> false
Symbol().for( "String" ) === Symbol().for( "String" );
> true
برای بازیابی کلید هر نماد از رجیستری نماد، از Symbol.keyFor()
استفاده کنید:
let mySymbol = Symbol.for( "Key." );
Symbol.keyFor( mySymbol ) ;
> "Key."
نمادهای "معروف".
نمادهای شناخته شده ویژگی های ثابت شی Symbol
هستند که هر کدام خود یک نماد هستند. نمادهای شناخته شده کلیدهای ویژگی منحصر به فردی را برای دسترسی و اصلاح روش های داخلی جاوا اسکریپت ارائه می کنند، در حالی که از بازنویسی ناخواسته رفتار اصلی جلوگیری می کنند.
Symbol;
> function Symbol()
asyncIterator: Symbol(Symbol.asyncIterator)
for: function for()
hasInstance: Symbol("Symbol.hasInstance")
isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
iterator: Symbol(Symbol.iterator)
keyFor: function keyFor()
length: 0
match: Symbol("Symbol.match")
matchAll: Symbol("Symbol.matchAll")
name: "Symbol"
prototype: Object { … }
replace: Symbol("Symbol.replace")
search: Symbol("Symbol.search")
species: Symbol("Symbol.species")
split: Symbol("Symbol.split")
toPrimitive: Symbol("Symbol.toPrimitive")
toStringTag: Symbol("Symbol.toStringTag")
unscopables: Symbol("Symbol.unscopables")
<prototype>: function ()
از آنجایی که نمادها یک ویژگی خاص برای ES6 هستند، این مقادیر نمادین برای توسعه دهندگانی که رفتار جاوا اسکریپت را بدون ارائه مشکلات سازگاری با عقب تغییر می دهند، به عنوان "نقاط توسعه" در نظر گرفته شده است.
مقادیر نمادهای شناخته شده اغلب با پیشوند @@
یا در %
پیچیده می شوند تا کلیدهای آنها را از نمونه های اولیه قابل تغییرشان متمایز کنند. به عنوان مثال، @@match
(یا %match%
) مرجعی است به Symbol.match
تغییرناپذیر، نه String.prototype.match
.
درک خود را بررسی کنید
آیا می توانید از new
برای ایجاد یک نماد استفاده کنید؟
کدام یک از موارد زیر نمادهای "مشهور" را توصیف می کند؟