สัญลักษณ์

Browser Support

  • Chrome: 38.
  • Edge: 12.
  • Firefox: 36.
  • Safari: 9.

Source

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

ไม่
ใช่

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

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