φυβλαςのβλογ
บล็อกของ phyblas



javascript เบื้องต้น บทที่ ๓๐: การประกาศตัวแปรหรือค่าคงที่ และการป้อนค่า
เขียนเมื่อ 2019/08/27 10:46


ตั้งแต่บทนี้ไปจะเป็นเนื้อหาที่เกี่ยวกับความสามารถที่เพิ่มเข้ามาใน ES6

ความสามารถที่เพิ่มมาใน ES6 นั้นมีมากมาย ซึ่งจะค่อยๆเขียนถึงในบทต่อๆไป

ความสามารถส่วนใหญ่ถูกเพิ่มมาตั้งแต่ใน ES2015 แล้ว แต่ก็มีบางส่วนเล็กๆน้อยๆเพิ่มเข้ามาใน ES2016, ES2017 หรือรุ่นหลังจากนั้นไปอีก โดยมีเพิ่มมาทุกปี แม้จะไม่ได้เพิ่มมาก

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



การประกาศตัวแปรด้วย let

แต่เดิมทีในจาวาสคริปต์ก่อนจะเข้าสู่ ES6 นั้นมีวิธีเดียวในการประกาศตัวแปร คือใช้ var

แต่ว่าใน ES6 ได้เพิ่มอีกวิธีในการประกาศตัวแปรเข้ามา คือใช้ let

เช่น เดิมทีประกาศตัวแปรด้วย var แบบนี้
var tuaprae = "ค่าตัวแปร"

แบบนี้สามารถใช้ let แทนได้ผลเหมือนกัน
let tuaprae = "ค่าตัวแปร"

ดูเผินๆแล้ว let ก็เหมือนกับ var แต่ว่ามีข้อแตกต่างกันอยู่ในรายละเอียดปลีกย่อย ซึ่งจะกล่าวถึงต่อไปนี้



let ไม่สามารถประกาศซ้ำได้

ตัวแปรที่ประกาศด้วย let หากมีการประกาศซ้ำอีกจะเกิดข้อผิดพลาด
let a = 1;
let a = 2; // ได้ SyntaxError: redeclaration of let a

แต่ถ้าใช้ var จะประกาศซ้ำกี่ครั้งก็ไม่มีผลอะไร

แม้แต่ตัวแปรที่ไม่ได้ประกาศด้วย let ถ้านำมาประกาศด้วย let ซ้ำก็ผิดพลาดเช่นกัน
a = 1;
let a = 2; // ได้ ReferenceError: can't access lexical declaration `a' before initialization



ตัวแปรที่ประกาศด้วย let จะใช้ได้แค่ในขอบเขตเท่านั้น

ปกติถ้าเราประกาศตัวแปรด้วย var สามารถจะประกาศตัวแปรที่ไหนก็ได้ แม้แต่ในโครงสร้าง if หรือ for หรือ while ที่ล้อมด้วย {}

เช่น
if (true) {
  var h = 1;
}
alert(h); // ได้ 1

แต่หากประกาศด้วย let ตัวแปรนั้นจะมีผลเฉพาะในกรอบวงเล็บปีกกา {} เท่านั้น เป็นการช่วยกำหนดขอบเขตของตัวแปรที่แน่ชัดขึ้น
if (true) {
  let k = 1;
}
alert(k); // ได้ ReferenceError: k is not defined

อันที่จริงแล้ว ต่อให้ไม่ได้อยู่ในโครงสร้าง if หรือ for หรือ while อะไรเลย ขอแค่มีวงเล็บปีกกาก็เป็นการกำหนดขอบเขตแล้ว ปีกกาสามารถใส่เข้ามาลอยๆเมื่อไหร่ก็ได้ เช่น
{let k = 1;}
alert(k); // ได้ ReferenceError: k is not defined

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

เช่นเขียนแบบนี้ ไม่เกิดข้อผิดพลาดใดๆ
{let z = 1;}
{let z = 2;}


มีข้อควรระวังอย่างหนึ่งคือไม่ควรใช้กับโครงสร้าง switch case เพราะโครงสร้างนี้จะใช้วงเล็บปีกกาเป็นตัวล้อมทั้งหมดแล้วกั้นแต่ละกรณีจากกันโดยใช้ break และ case แต่ถ้ามีการประกาศตัวแปรขึ้น แม้ว่าจะในคนละกรณีก็ตาม จะเกิดข้อผิดพลาดขึ้น เพราะว่าในขอบเขตกรอบ {} เดียวกันไม่สามารถประกาศตัวแปรเดียวกันซ้ำได้นั่นเอง

เช่น
let a = 1;
switch (a) {
  case 1:
    let g = "ก";
    break;
  case 2:
    let g = "ข";
}
// ได้ SyntaxError: redeclaration of let g



การประกาศตัวแปรค่าคงที่ด้วย const

อีกวิธีในการประกาศตัวแปรที่เพิ่มเข้ามาใน ES6 คือใช้ const

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

แต่ใน ES6 นี้ const จึงได้ถูกใส่เป็นความสามารถโดยพื้นฐานในจาวาสคริปต์อย่างเป็นทางการ

การใช้ const จะเหมือนกับ let แค่ตัวแปรที่ประกาศด้วย const จะไม่สามารถเปลี่ยนแปลงภายหลังได้ หากลองป้อนค่าใหม่ลงไปจะเกิดข้อผิดพลาด

ชื่อตัวแปรที่ใช้เป็นค่าคงที่จะมีข้อจำกัดเช่นเดียวกับเมื่อใช้ let หรือ var เพียงแต่ว่า ปกติโดยธรรมเนียมปฏิบัติแล้วจะใช้ตัวพิมพ์ใหญ่ล้วนแทนค่าคงที่ เพื่อให้เห็นแล้วรู้ทันทีว่าเป็นค่าคงที่ ในการแบ่งคำจะใช้ขีดล่าง _

ตัวอย่าง
const KHAKHONGTHI_DORADORA = 129.3;
KHAKHONGTHI_DORADORA = 0;
alert(KHAKHONGTHI_DORADORA); // ได้ TypeError: invalid assignment to const `KHAKHONGTHI_DORADORA'

const THAWAISAT = "ข้าพเจ้าขอสาบานว่าจะจงรักภักดีต่อชาติ";
THAWAISAT = "ข้าพเจ้ารักเงิน"; // ได้ TypeError: invalid assignment to const `THAWAISAT'
var THAWAISAT = "ข้าพเจ้าหวงอำนาจ"; // ได้ SyntaxError: redeclaration of const THAWAISAT
let THAWAISAT = "ข้าพเจ้ารักเงินหวงอำนาจ"; // ได้ SyntaxError: redeclaration of const THAWAISAT

เพียงแต่ว่าการใช้ const นั้นแค่ป้องกันการป้อนค่าใหม่ลงไปในตัวแปรนั้นโดยตรงเท่านั้น แต่ถ้าข้อมูลเป็นออบเจ็กต์ พรอเพอร์ตีในออบเจ็กต์นั้นยังสามารถเปลี่ยนแปลงค่าได้อยู่ดี ถ้าจะป้องกันการเปลี่ยนแปลงโดยสมบูรณ์อาจจะใช้ Object.freeze ไปด้วย
const KLONG = { yao: 10 };
KLONG.yao = 11;
alert(KLONG.yao); // ได้ 11
Object.freeze(KLONG);
KLONG.yao = 12;
alert(KLONG.yao); // ได้ 11

ในการใช้งานจริงจะใช้แต่ let ไม่ใช้ const เลยก็ไม่ได้มีปัญหาแต่อย่างใด เพียงแต่การใช้ const จะเป็นการช่วยให้เรารู้แน่ชัดว่าตัวแปรนี้จะไม่มีการเปลี่ยนแปลง แบ่งแยกกันชัดเจน มีส่วนช่วยให้โปรแกรมเข้าใจได้ง่ายขึ้น



การป้อนค่าให้ตัวแปรทีละหลายตัว

ใน ES6 นั้นสามารถนำค่าจากแถวลำดับมาแตกลงในตัวแปรพร้อมกันหลายตัวได้ โดยเขียนตัวแปรที่รับค่าในรูปของแถวลำดับ คือล้อมด้วย [ ]

เช่น
let [a, b, c] = ["ข้าว", "บะหมี่", "ขนมปัง"];
alert(a); // ได้ ข้าว
alert(b); // ได้ บะหมี่
alert(c); // ได้ ขนมปัง

ไม่ว่าจะเป็นการประกาศด้วย let หรือ var หรือ const หรือป้อนค่าให้ตัวแปรที่มีอยู่เดิมแล้วก็ทำแบบนี้ได้เหมือนกันหมด

แต่ถ้าทำแบบนี้ใน ES3 หรือ ES5 ก็จะเกิดข้อผิดพลาดขึ้น

กรณีที่จำนวนตัวแปรที่รับค่ามีน้อยกว่าจำนวนค่าในแถวลำดับที่ให้ค่า ตัวที่เกินมาจะถูกมองข้ามไป
let [d, e] = ["โลภ", "โกรธ", "龍"];
alert(d); // ได้ โลภ
alert(e); // ได้ โกรธ
ในทางกลับกัน หากตัวแปรที่รับค่ามีจำนวนมากกว่า ตัวที่เกินมาก็จะได้ undefined
let [f, g, h] = ["ง่วง", "นอน"];
alert(f); // ได้ ง่วง
alert(g); // ได้ นอน
alert(h); // ได้ undefined

หากมีค่าที่ต้องการเว้นก็ใช้พิมพ์จุลภาคต่อกันโดยไม่คั่นด้วยแปรใดๆได้ แบบนี้ , , , เช่น
let [k, , , l, , m] = ["ไก่", "จิก", "เด็ก", "โง่", "บน", "โอ่ง"];
alert(k); // ได้ ไก่
alert(l); // ได้ โง่
alert(m); // ได้ โอ่ง



การสร้างฟังก์ชันที่คืนค่าหลายตัวพร้อมกัน

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

เช่น ฟังก์ชันที่ให้ค่าผลคูณและผลหารพร้อมกัน
let khunhan = function(a, b) {
  return [a * b, a / b];
};

let [phonkhun, phonhan] = khunhan(5, 4);
alert(phonkhun); // ได้ 20
alert(phonhan); // ได้ 1.25

alert(khunhan(3, 2)); // ได้ 6,1.5



สรุปส่งท้าย

ความสามารถที่เพิ่มเข้ามานี้ ทำให้การใช้งานใน ES6 มีความยืดหยุ่นและสะดวกขึ้นมาก

โดยทั่วไปแล้วในสิ่งแวดล้อมที่ใช้ ES6 ได้จะใช้ let หรือ const แทน var เนื่องจากปลอดภัยกว่า

ตัวอย่างที่จะเขียนถึงต่อไปในบทต่อจากนี้ก็จะใช้ let แทน var ทั้งหมด




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

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

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

หมวดหมู่

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

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

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
python
-- numpy
-- matplotlib

-- pandas
-- pytorch
maya
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
javascript
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
เรียนภาษาจีน
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



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

  ค้นหาบทความ

  บทความแนะนำ

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

ไทย

日本語

中文