สัญลักษณ์พื้นฐานแสดงค่าที่ไม่ซ้ำกันซึ่งจะไม่ทับซ้อนกับค่าอื่นๆ รวมถึงค่าของสัญลักษณ์พื้นฐานอื่นๆ สตริงพื้นฐาน 2 รายการที่ประกอบด้วยอักขระเหมือนกันจะถือว่ามีค่าเท่ากันโดยสมบูรณ์ในกรณีต่อไปนี้
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
อย่างไรก็ตาม จะไม่มีสัญลักษณ์ 2 รายการที่สร้างโดยใช้ฟังก์ชัน Symbol()
ที่เท่ากันโดยสมบูรณ์
Symbol() === Symbol()
> false
ลักษณะนี้ช่วยให้คุณใช้สัญลักษณ์เป็นคีย์พร็อพเพอร์ตี้ที่ไม่ซ้ำกันในออบเจ็กต์ได้ ซึ่งจะช่วยป้องกันไม่ให้คีย์ของโค้ดอื่นที่อาจเพิ่มลงในออบเจ็กต์นั้นซ้ำกัน
const mySymbol = Symbol( "Desc" );
const myObject = {};
myObject[mySymbol] = "propSymbol";
myObject
> Object { Symbol("Desc"): "propSymbol" }
สัญลักษณ์มี 3 ประเภท ได้แก่
- สัญลักษณ์ที่สร้างด้วย
Symbol()
- สัญลักษณ์ที่แชร์ซึ่งตั้งค่าและดึงมาจากรีจิสทรีสัญลักษณ์ทั่วโลกโดยใช้
Symbol.for()
- "สัญลักษณ์ที่รู้จักกันดี" ที่กําหนดเป็นพร็อพเพอร์ตี้แบบคงที่ในแอบเจ็กต์ 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
ซึ่งแต่ละรายการเป็นสัญลักษณ์ สัญลักษณ์ที่รู้จักกันดีจะให้คีย์พร็อพเพอร์ตี้ที่ไม่ซ้ำกันสำหรับการเข้าถึงและการแก้ไขเมธอดในตัวของ JavaScript ในขณะเดียวกันก็ป้องกันไม่ให้มีการเขียนทับลักษณะการทํางานหลักโดยไม่ตั้งใจ
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 ค่าสัญลักษณ์เหล่านี้จึงมีไว้เพื่อใช้เป็น "จุดขยาย" สำหรับนักพัฒนาซอฟต์แวร์ที่แก้ไขลักษณะการทํางานของ JavaScript โดยไม่ก่อให้เกิดปัญหาความเข้ากันได้ย้อนหลัง
ค่าสัญลักษณ์ที่รู้จักกันดีมักจะมีรูปแบบเป็นคำนำหน้า @@
หรืออยู่ภายใน %
เพื่อแยกคีย์ออกจากโปรโตไทป์ที่เปลี่ยนแปลงได้ เช่น @@match
(หรือ %match%
) เป็นการอ้างอิงถึง Symbol.match
ที่ไม่เปลี่ยนแปลง ไม่ใช่ String.prototype.match
ทดสอบความเข้าใจ
คุณใช้ new
เพื่อสร้างสัญลักษณ์ได้ไหม
ข้อใดต่อไปนี้อธิบายสัญลักษณ์ "ที่รู้จักกันดี"