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