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



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


ตั้งแต่บทนี้ไปจะเป็นเนื้อหาที่เกี่ยวกับความสามารถที่เพิ่มเข้ามาใน 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

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

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

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

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



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

  ค้นหาบทความ

  บทความแนะนำ

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

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文