สัญลักษณ์

สัญลักษณ์เป็นที่ค่อนข้างใหม่ แบบดั้งเดิมที่เปิดตัวใน 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 ค่าสัญลักษณ์เหล่านี้ ที่ตั้งใจจะใช้เป็น "จุดขยายสัญญาณ" สำหรับนักพัฒนาซอฟต์แวร์ซึ่งแก้ไข โดยไม่เพิ่มปัญหาด้านความเข้ากันได้แบบย้อนหลัง

ค่าสัญลักษณ์ที่รู้จักกันดีมักจะได้รับการจัดรูปแบบโดยใช้ คำนำหน้า @@ หรือรวมไว้ใน % เพื่อ แยกความแตกต่างระหว่างคีย์กับต้นแบบที่เปลี่ยนแปลงได้ เช่น @@match (หรือ %match%) เป็นการอ้างอิงถึง Symbol.match ที่เปลี่ยนแปลงไม่ได้ ไม่ใช่ String.prototype.match

ตรวจสอบความเข้าใจ

คุณใช้ new สร้างสัญลักษณ์ได้ไหม

ไม่ได้
ใช่

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

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