φυβλαςのβλογ
phyblas的博客



javascript เบื้องต้น บทที่ ๓๕: ซิมโบล
เขียนเมื่อ 2020/02/03 13:32
แก้ไขล่าสุด 2024/01/24 22:22


ในบทที่ ๓ ได้เขียนถึงข้อมูลชนิดต่างๆที่มีตั้งแต่ ES3 ไปแล้วว่ามี ๕ ชนิด ตัวเลข (number), สายอักขระ (string), บูล (boolean), ออบเจ็กต์ (object), ฟังก์ชัน (function)

ใน ES6 มีชนิดข้อมูลเพิ่มมาอีกอย่างคือชนิดที่เรียกว่าซิมโบล (symbol)

นี่เป็นข้อมูลที่มีความเข้าใจยากหน่อย และอาจไม่ได้ใช้งานมากเท่าชนิดอื่น แต่ก็มีประโยชน์ในการใช้งานในบางกรณีจึงได้ถูกเพิ่มเข้ามา

ในบทนี้จะพูดถึงการสร้างและการใช้งานซิมโบล



การสร้างซิมโบล

ข้อมูลชนิดซิมโบลสามารถสร้างขึ้นได้โดยฟังก์ชัน Symbol
let sol = Symbol();
alert(typeof sol); // ได้ symbol

ซิมโบลจะไม่เปลี่ยนเป็นสายอักขระโดยอัตโนมัติ ดังนั้นถ้าใช้กับ alert หรือนำไปคำนวณกับข้อมูลชนิดอื่นจะเกิดข้อผิดพลาด แต่สามารถใช้เมธอด .toString เพื่อเปลี่ยนเป็นสายอักขระโดยตรงได้
alert(sol.toString()); // ได้ Symbol()
alert(sol); // ได้ TypeError: can't convert symbol to string
sol+1; // ได้ TypeError: can't convert symbol to number

Symbol ใช้เป็นฟังก์ชันสร้างข้อมูลโดยตรงเท่านั้น ใช้ new แบบคอนสตรักเตอร์ไม่ได้ ต่างจากพวก Number, String, Object ที่สามารถใช้ได้
let sol = new Symbol() // ได้ TypeError: Symbol is not a constructor

สามารถใส่คำอธิบายลงไปในวงเล็บตอนสร้างซิมโบลได้ คำที่ใส่ไปจะปรากฏตอนใช้ toString()
let sol = Symbol("ซิม")
alert(sol.toString()) // ได้ Symbol(ซิม)




คุณสมบัติของซิมโบล

คุณสมบัติที่สำคัญของซิมโบลก็คือไม่ว่าจะไปเปรียบเทียบด้วย == หรือ === กับอะไรก็จะได้ false หมด แม้แต่ซิมโบลที่ถูกสร้างให้เหมือนกันก็ตาม

แต่จะได้ true เมื่อเทียบกับตัวมันเองเท่านั้น หรือเป็นตัวแปรที่รับค่าจากซิมโบลตัวนั้นโดยตรง
let sol1 = Symbol("ซิม");
let sol2 = Symbol("ซิม");
alert(sol1==sol2); // ได้ false
alert(sol1===sol2); // ได้ false
alert(sol1=="sol1"); // ได้ false
alert(sol1==sol1); // ได้ true
alert(sol1===sol1); // ได้ true

let sol3 = sol1;
alert(sol1==sol3); // ได้ true
alert(sol1===sol3); // ได้ true

ในตัวอย่างนี้ sol1 และ sol2 ต่างก็คือ Symbol("ซิม") เหมือนกัน แต่พอมาเปรียบเทียบกันกลับได้ false นั่นเพราะซิมโบลแต่ละตัวจะถือว่าไม่ซ้ำกับใครนอกจากตัวมันเอง

แต่ sol3 ในที่นี้คือแทน sol1 โดยตรง ดังนั้นจึงถือเป็นซิมโบลตัวเดียวกัน เมื่อนำมาเปรียบเทียบจึงถือว่าเท่ากัน

คุณสมบัติตรงนี้คือสิ่งที่เป็นเอกลักษณ์ของซิมโบล ซึ่งจะถูกนำไปใช้ประโยชน์




การใช้ซิมโบลแทนค่าคงที่

สมมุติว่าเราต้องการค่าคงที่ที่แทนอะไรบางอย่างเพื่อแยกว่าเป็นของคนละชนิดกัน เพื่อใช้แยกกรณี หรือเป็นตัวเลือกอะไรบางอย่าง

โดยทั่วไปตัวอย่างที่เห็นมากก็คือใช้ตัวเลขแทนเพื่อแบ่งแยก เช่น
const MISAKA = 0;
const SHIRAI = 1;
const UIHARU = 2;
const SATEN = 3;

function f(k) {
  if (k === MISAKA) {
    // คำสั่งอะไรบางอย่าง
  }
  else if (k === SHIRAI) {
    // คำสั่งอะไรบางอย่าง
  }
  else {
    // คำสั่งอะไรบางอย่าง
  }
}

let u = UIHARU, m = MISAKA;
f(m); // เข้าเงื่อนไข if แรก
f(SHIRAI); // เข้าเงื่อนไขที่ ๒
f(u); // เข้าเงื่อนไข else สุดท้าย

การใช้ตัวเลขแบบนี้ก็ใช้ได้ก็จริง แต่ว่าถ้าแบบนี้หมายความว่าไม่ต้องแทนด้วยตัวแปรค่าคงที่นั้น แต่ใส่ตัวเลข 0, 1, 2, ... ไปธรรมดาก็ใช้งานได้เหมือนกัน เพราะเนื้อในค่าในนี้จริงๆก็เป็นตัวเลข
let x = 0;
if (x === MISAKA) {
  // คำสั่งอะไรบางอย่าง
}

แบบนี้ผลที่ได้ก็จะเป็นจริงแล้วเข้าเงื่อนไขได้เหมือนกัน

แม้ที่จริงตรงนี้ใช้ตัวเลขแทนไปเลยก็ไม่ใช่ปัญหาอะไรหนัก แต่เพื่อความอ่านง่ายจึงเก็บไว้ในข้อมูลที่เป็นตัวแปร จะง่ายกว่าต้องมาจำว่าเลขอะไรแทนอะไร อีกทั้งถ้าเผลอใช้เลขซ้ำกันขึ้นมาก็จะเกิดบั๊กได้ง่าย

อีกทั้งยังต้องกำหนดเป็นตัวเลขทั้งๆที่จริงๆเราแค่ต้องการตัวแปรที่แค่แยกแยะให้เห็นว่าเป็นข้อมูลคนละตัวกันเท่านั้นเอง ไม่จำเป็นต้องเป็นตัวเลข ขอแค่เป็นสิ่งที่ต่างกัน

ดังนั้นตรงนี้เราสามารถใช้ซิมโบลแทนได้ เพราะซิมโบลมีคุณสมบัติที่จะไม่ซ้ำกับตัวใดๆที่นอกเหนือจากมันเอง
const MISAKA = Symbol();
const SHIRAI = Symbol();
const UIHARU = Symbol();
const SATEN = Symbol();

let x = SATEN;
alert(x == SATEN); // ได้ true
alert(x == MISAKA); // ได้ false

แบบนี้จะแน่นอนได้ว่าค่าคงที่แต่ละตัวไม่มีใครมาซ้ำกับตัวนั้นเองหรือตัวแปรที่ใช้เท่ากับ = ป้อนให้ตัวนั้นโดยตรงเท่านั้น

ซิมโบลทุกตัวจะสร้างเป็น Symbol() เฉยๆโดยไม่ต้องใส่คำอธิบายในวงเล็บเลยเหมือนกันหมดเลยก็ไม่มีปัญหาอะไร เพราะยังไงก็ถือเป็นคนละตัวกันถ้าสร้างใหม่แยกกัน หรืออาจใส่คำอธิบายไปในวงเล็บด้วยก็ได้ เช่น Symbol("นี่คือซิม") แต่ก็ไม่ได้มีผลอะไร




การใช้ซิมโบลแทนคีย์ของออบเจ็กต์

ซิมโบลสามารถใช้เป็นคีย์ของออบเจ็กต์ได้ด้วย

ตัวอย่าง สร้างซิมโบลขึ้นมาแล้วใช้เป็นคีย์ในออบเจ็กต์โดยการใส่วงเล็บเหลี่ยม [ ] คร่อมชื่อตัวแปร
const INDEX = Symbol();
const TOUMA = Symbol();
let toaru = {
    [INDEX]: 10000,
    [TOUMA]: 100
};

alert(toaru.INDEX); // ได้ undefined
alert(toaru[INDEX]); // ได้ 10000
alert(toaru["INDEX"]); // ได้ undefined
alert(toaru[TOUMA]); // ได้ 100
alert(toaru[Symbol()]); // ได้ undefined
let i2 = INDEX;
alert(toaru[i2]); // ได้ 10000

จะเห็นว่าออบเจ็กต์นี้ใช้คีย์เป็นซิมโบลเหมือนกัน แต่ถือเป็นคีย์คนละตัวกัน และถึงสร้างซิมโบลใหม่ก็ไม่อาจมาใช้แทนได้ ที่จะใช้แทนได้ก็มีแต่ตัวแปรที่ตั้งค่าให้เป็นซิมโบลตัวนั้นเองเท่านั้น

ประโยชน์จากการใช้ซิมโบลเป็นชื่อพรอเพอร์ตีก็คือสามารถสร้างสิ่งที่เรียกว่าพรอเพอร์ตีส่วนตัว (private property) และเมธอดส่วนตัว (private method) ให้กับออบเจ็กต์ได้

แต่วิธีนี้มักจะใช้เมื่อสร้างคลาสขึ้นมาในมอดูล ดังนั้นก็จะยกไปเขียนถึงในบทถัดไปซึ่งว่าด้วยเรื่องของการสร้างมอดูล






-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> javascript

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ