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