สัญลักษณ์

สัญลักษณ์เป็นแบบดั้งเดิมที่ค่อนข้างใหม่ ซึ่งเปิดตัวไปแล้วใน 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 เพื่อสร้างสัญลักษณ์ได้ไหม

ไม่ได้
ใช่

ข้อใดต่อไปนี้อธิบายสัญลักษณ์ "เป็นที่รู้จักดี"

พร็อพเพอร์ตี้แบบคงที่ของออบเจ็กต์ "สัญลักษณ์"
สัญลักษณ์ที่คุณใช้บ่อย
คีย์พร็อพเพอร์ตี้ที่ไม่ซ้ำกันสำหรับการเข้าถึงและแก้ไขเมธอดในตัวของ JavaScript