โพสต์นี้เกี่ยวกับ Symbol()
, มาพร้อมกับตัวอย่างจริงที่ฉันสามารถหา / ทำและข้อเท็จจริง & คำจำกัดความที่ฉันสามารถหาได้
TLDR;
นี่Symbol()
คือชนิดข้อมูลที่แนะนำพร้อมกับการเปิดตัว ECMAScript 6 (ES6)
มีข้อเท็จจริงที่น่าสงสัยเกี่ยวกับสัญลักษณ์สองอย่าง
ชนิดข้อมูลแรกและชนิดข้อมูลเท่านั้นใน JavaScript ซึ่งไม่มีตัวอักษร
ตัวแปรใด ๆ ที่กำหนดไว้กับSymbol()
ได้รับเนื้อหาที่ไม่ซ้ำกัน แต่มันไม่ได้จริงๆส่วนตัว
ข้อมูลใด ๆ ที่มีของตัวเองสัญลักษณ์และสำหรับข้อมูลเดียวกันสัญลักษณ์จะเป็นแบบเดียวกัน ข้อมูลเพิ่มเติมในย่อหน้าต่อไปนี้มิฉะนั้นจะไม่ใช่ TLRD :)
ฉันจะเริ่มต้นสัญลักษณ์ได้อย่างไร
1. เพื่อให้ได้ตัวระบุที่ไม่ซ้ำกับค่าที่ debuggable
คุณสามารถทำได้ด้วยวิธีนี้:
var mySymbol1 = Symbol();
หรือด้วยวิธีนี้:
var mySymbol2 = Symbol("some text here");
"some text here"
สตริงไม่สามารถสกัดได้จากสัญลักษณ์มันเป็นเพียงคำอธิบายสำหรับการดีบักวัตถุประสงค์ มันไม่ได้เปลี่ยนพฤติกรรมของสัญลักษณ์ในทางใดทางหนึ่ง แม้ว่าคุณจะทำได้console.log
(ซึ่งยุติธรรมเนื่องจากค่าสำหรับการดีบักเพื่อไม่ให้เกิดข้อผิดพลาดในการบันทึกที่มีรายการบันทึกอื่น ๆ ):
console.log(mySymbol2);
// Symbol(some text here)
2. เพื่อรับสัญลักษณ์สำหรับข้อมูลสตริงบางอย่าง
ในกรณีนี้มูลค่าของสัญลักษณ์ถูกนำมาพิจารณาจริงและวิธีนี้สองสัญลักษณ์อาจไม่ซ้ำกัน
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
มาเรียกสัญลักษณ์เหล่านี้ว่า "second-type" พวกเขาจะไม่ตัดกับสัญลักษณ์ "ประเภทแรก" (เช่นที่กำหนดด้วยSymbol(data)
) ในทางใดทางหนึ่ง
สองย่อหน้าถัดไปเกี่ยวข้องเฉพาะกับประเภทแรกเท่านั้นสัญลักษณ์เท่านั้น
ฉันจะได้รับประโยชน์จากการใช้ Symbol แทนประเภทข้อมูลที่เก่ากว่าได้อย่างไร
ก่อนอื่นมาพิจารณาวัตถุชนิดข้อมูลมาตรฐาน เราสามารถกำหนดคู่คีย์ - ค่าที่นั่นและเข้าถึงค่าได้โดยการระบุคีย์
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
ถ้าเรามีสองคนที่มีชื่อปีเตอร์ล่ะ
ทำสิ่งนี้:
var persons = {"peter":"first", "peter":"pan"};
จะไม่สมเหตุสมผล
ดังนั้นดูเหมือนจะเป็นปัญหาของคนสองคนที่แตกต่างกันอย่างสิ้นเชิงที่มีชื่อเหมือนกัน Symbol()
ลองมาแล้วดูออกใหม่ มันเหมือนคนในชีวิตจริง - บุคคลใดมีเอกลักษณ์แต่ชื่อของพวกเขาจะเท่ากัน มานิยาม "คน" สองคนกัน
var a = Symbol("peter");
var b = Symbol("peter");
ตอนนี้เรามีคนสองคนที่มีชื่อเหมือนกัน บุคคลของเราแตกต่างกันหรือไม่? พวกเขาคือ; คุณสามารถตรวจสอบสิ่งนี้:
console.log(a == b);
// false
เราจะได้ประโยชน์อย่างไรที่นั่น?
เราสามารถสร้างสองรายการในวัตถุของคุณสำหรับบุคคลอื่นและพวกเขาไม่สามารถเข้าใจผิดในทางใดทางหนึ่ง
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
หมายเหตุ:
มันมีค่าที่จะสังเกตเห็นว่าการ stringing วัตถุด้วยJSON.stringify
จะวางคู่ทั้งหมดที่เริ่มต้นด้วยสัญลักษณ์เป็นคีย์
การดำเนินการObject.keys
จะไม่ส่งคืนSymbol()->value
คู่ดังกล่าว
การใช้การกำหนดค่าเริ่มต้นนี้เป็นไปไม่ได้ที่จะทำผิดพลาดรายการสำหรับบุคคลที่หนึ่งและสอง การโทรconsole.log
หาพวกเขาอย่างถูกต้องจะส่งชื่อที่สองออกมาอย่างถูกต้อง
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
เมื่อใช้ในวัตถุมันแตกต่างอย่างไรเมื่อเปรียบเทียบกับการกำหนดคุณสมบัติที่ไม่นับจำนวน
แท้จริงแล้วมีวิธีการกำหนดคุณสมบัติที่จะซ่อนObject.keys
และการแจงนับ นี่มันคือ:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
มีความแตกต่างอะไรบ้างSymbol()
? ความแตกต่างคือคุณยังสามารถรับคุณสมบัติที่กำหนดด้วยObject.defineProperty
วิธีปกติ:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
และหากนิยามด้วย Symbol ตามวรรคก่อนหน้า:
fruit = Symbol("apple");
คุณจะมีความสามารถในการรับค่าของมันเฉพาะเมื่อรู้ว่าตัวแปรคือ
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
ยิ่งไปกว่านั้นการกำหนดคุณสมบัติอื่นภายใต้คีย์"apple"
จะทำให้วัตถุวางอันเก่า (และหากฮาร์ดโค้ดมันอาจทำให้เกิดข้อผิดพลาด) ดังนั้นไม่มีแอปเปิ้ลอีกต่อไป! ที่น่าเสียดาย. อ้างถึงย่อหน้าก่อนหน้าสัญลักษณ์ที่ไม่ซ้ำกันและการกำหนดคีย์ที่Symbol()
จะทำให้มันเป็นเอกลักษณ์
การแปลงและตรวจสอบประเภท
ไม่เหมือนกับชนิดข้อมูลอื่น ๆ เป็นไปไม่ได้ที่จะแปลงเป็นSymbol()
ชนิดข้อมูลอื่น
มันเป็นไปได้ที่จะ "ให้" Symbol(data)
สัญลักษณ์ขึ้นอยู่กับชนิดข้อมูลดั้งเดิมโดยการเรียก
ในแง่ของการตรวจสอบประเภทไม่มีอะไรเปลี่ยนแปลง
function isSymbol ( variable ) {
return typeof someSymbol === "symbol";
}
var a_Symbol = Symbol("hey!");
var totally_Not_A_Symbol = "hey";
console.log(isSymbol(a_Symbol)); //true
console.log(isSymbol(totally_Not_A_Symbol)); //false