diff --git a/.idea/dictionaries/DELL.xml b/.idea/dictionaries/DELL.xml
new file mode 100644
index 0000000..d88077d
--- /dev/null
+++ b/.idea/dictionaries/DELL.xml
@@ -0,0 +1,7 @@
+
+
+
+ frist
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 37601f0..9199649 100644
--- a/README.md
+++ b/README.md
@@ -1,55 +1,17 @@
-# JavaScript ยุคสมัยใหม่
+# มาเรียนรู้ JavaScript ยุคสมัยใหม่กันเถอะ!
-
-
-
-
-## เนื้อหาเกี่ยวกับอะไร
-
-เหตุผลที่เขียนบทความชุดนี้ เพราะหลังจากเขียนหนังสือเล่มดังกล่าวไปแล้ว (ตามรูปข้างบน) เทคโนโลยีจาวาสคริปต์ก็ดูเหมือนพัฒนาต่อเนื่อง (ยังไม่นิ่ง)
-ด้วยเหตุนี้ ....
-
-* เนื้อหาทั้งหมดต่อไปนี้ จะเหมือนเป็นภาคต่อจากหนังสือดังกล่าว
-* จะทบทวนจาวาสคริปต์ตามมาตรฐานเก่า ES5 นิดหน่อย
-* จะเป็นการพาทัวร์ภาษาจาวาสคริปต์ (JavaScript) ยุคสมัยใหม่ตามมาตรฐาน ES6
-* จะพูดถึงภาษาจาวาสคริปต์ (JavaScript) ยุคสมัยใหม่ตามมาตรฐาน ES7, ES8
-* รวมทั้งเพิ่มเนื้อหาที่ไม่อยู่ในหนังสืออีกมากมาย
-* ทั้งนี้เนื้อหาจะต่างจากหนังสือข้างต้น ไม่เหมือนกันซะเท่าไร
-* ซึ่งตอนนี้ผมยังเขียนสรุปไม่เสร็จดี ว่างๆ ก็จะมาอัพเดตใหม่เรื่อยๆ
-
-*** เขียนเสร็จไปแล้ว 20%
-
-*** ใครเอาเนื้อหาผมไปใช้ โปรดให้เครดิตลิงค์ต้นฉบับต้นด้วยนะคร๊าบบบบบ
-
-ถ้าสนใจข่าวสารไอที ติดตามได้ที่เพจ
-
-* https://www.facebook.com/programmerthai/
-
-สามารถให้คำชี้แนะ แนะนำผม คอมเมนต์ผมได้ตลอดเวลาที่
-
-* http://www.patanasongsivilai.com/javascript.html
-
-## ถ้าสนใจเล่มนี้สามารถสั่งซื้อได้ที่
-
-* [ศูนย์หนังสือจุฬา]( http://www.chulabook.com/description.asp?barcode=9786160825394)
-* [ร้านนายอินทร์](https://www.naiin.com/product/detail/191081/)
-* [ร้าน Book Smile](http://www.booksmile.co.th/คอมพิวเตอร์อินเทอร์เน็ต/พัฒนาเว็บแอบพลิเคชั่นด้วย-JavaScript.html)
-* [ร้าน kinokuniya thailand](https://thailand.kinokuniya.com/bw/9786160825394)
-* [ผ่านฟ้าบุ๊คเซ็นเตอร์] (http://www.phanpha.com/item/พัฒนาเว็บแอปพลิเคชั่นด้วย-javascript)
-* [ซีเอ็ดบางสาขา]( https://www.se-ed.com/product/พัฒนาเว็บแอปพลิเคชั่นด้วย-JavaScript.aspx?no=9786160825394)
-* และร้านหนังสืออื่น ๆ ที่ไม่ได้กล่าว
+
## สารบัญ
-* [บทที่ 1 แนะนำภาษาจาวาสคริปต์](#บทที่-1-แนะนำภาษาจาวาสคริปต์)
-* [บทที่ 2 ทวน ES5 (มาตรฐานเก่า)](#บทที่-2-ทวน-es5-มาตรฐานเก่า)
-* [บทที่ 3 แนะนำ ES6](#บทที่-3-แนะนำ-es6)
-* [บทที่ 4 แนะนำ ES7](#บทที่-4-แนะนำ-es7)
-* [บทที่ 5 แนะนำ ES8](#บทที่-5-แนะนำ-es8)
+* [แนะนำภาษาจาวาสคริปต์](#แนะนำภาษาจาวาสคริปต์)
+* [ทวน ES5 (มาตรฐานเก่า)](#ทวน-es5-มาตรฐานเก่า)
+* [แนะนำ ES6](#แนะนำ-es6)
+* [แนะนำ ES7](#แนะนำ-es7)
+* [แนะนำ ES8](#แนะนำ-es8)
+* [แนะนำ ES9 และ ES10](#แนะนำ-es9-และ-es10)
-
-
-## บทที่ 1 แนะนำภาษาจาวาสคริปต์
+## แนะนำภาษาจาวาสคริปต์
### เกริ่นนำ
@@ -59,13 +21,13 @@

-* นักพัฒนาซอฟต์แวร์ส่วนใหญ่ล้วนรู้จักภาษาจาวาสคริปต์ ซึ่งถือว่านิยมใช้กันมากภาษาหนึ่งในโลก ถ้าศึกษาอย่างผิวเผินก็อาจคิดว่าง๊ายง่าย แต่เมื่อศึกษาลงลึก ๆ แล้ว จะพบว่ามันโคตรจะอินดี้ เป็นภาษาปราบเซียนตัวหนึ่ง จนคนไม่ค่อยเข้าใจกันมากเท่าไรนัก จนหารู้ไม่ว่ามันมีความสามารถแฝงที่ซ้อนเร้นอยู่เยอะเลย
+* นักพัฒนาซอฟต์แวร์ส่วนใหญ่ล้วนรู้จักภาษาจาวาสคริปต์ ซึ่งถือว่านิยมใช้กันมากภาษาหนึ่งในโลก ถ้าศึกษาอย่างผิวเผินก็อาจคิดว่าง๊ายง่าย แต่เมื่อศึกษาลงลึก ๆ แล้ว จะพบว่ามัน**โคตรจะอินดี้ เป็นภาษาปราบเซียนตัวหนึ่ง** จนคนไม่ค่อยเข้าใจกันมากเท่าไรนัก จนหารู้ไม่ว่ามันมีความสามารถแฝงที่ซ้อนเร้นอยู่เยอะเลย
* จาวาสคริปต์ไม่ใช่ภาษา Java นะครับ คนละภาษา (คนมักสับสนกัน)

-* คนส่วนใหญ่รู้แค่ว่าใช้จาวาสคริปต์ร่วมกับภาษา HTML (ปัจจุบันเวอร์ชั่น HTML5) กับ CSS (ปัจจุบันเวอร์ชั่น CSS3) เพื่อทำให้เว็บมันไดนามิก ฟุ้งฟิ้ง กรุ้งกิ๊ง (มันดังในฝั่ง Font-end มานาน)
+* คนส่วนใหญ่รู้แค่ว่าใช้จาวาสคริปต์ร่วมกับภาษา HTML (ปัจจุบันเวอร์ชั่น HTML5.1) กับ CSS (ปัจจุบันเวอร์ชั่น CSS3) เพื่อทำให้เว็บมันไดนามิก ฟุ้งฟิ้ง กรุ้งกิ๊ง (มันดังในฝั่ง Font-end มานาน)
* แต่ปัจจุบันนี้จาวาสคริปต์สมัยใหม่ มันก้าวหน้าไปไกลมาก ๆๆๆ เพราะสามารถทำงานอยู่ฝั่งเซิร์ฟเวอร์ได้ (Back-end) ด้วย Node.js แม้แต่เอาไปทำแอพบนโมบาย หรือแม้แต่โรบอท ก็ยังทำได้ด้วย ….อายย่ะ
@@ -83,13 +45,13 @@
* ต้องเข้าใจอย่างนี้นะครัช เนื่อง ES6 มันใหญ่โตอลังการงานสร้างมาก คืนรอปล่อยออกมาหมดทีเดียว ก็คงรอหลายชาติภพ อาจทำให้มีเสียงบ่นตามมาได้ ด้วยเหตุนี้เข้าถึงเพิ่มฟีเจอร์เล็กยิบ ๆ ย่อย ๆ มาใส่ไว้ในเวอร์ชั่นหลัง ๆ แทน
-* โดยคาดว่าจากนี้ไป จะมีการประกาศเวอร์ชั่นใหม่ทุก ๆ ปี โดยให้คิดเสียว่า ES6 เหมือนโปรแกรมหลัก ส่วนเวอร์ชั่นที่ออกตามทีหลัง ไม่ได้ว่าจะเป็น ES7, ES8 และ ESXXXXX มันก็คือการอัพเดตซอฟต์แวร์ อะไรประมาณนี้
+* โดยคาดว่าจากนี้ไป จะมีการประกาศเวอร์ชั่นใหม่ทุก ๆ ปี โดยให้คิดเสียว่า ES6 เหมือนโปรแกรมหลัก ส่วนเวอร์ชั่นที่ออกตามทีหลัง ไม่ได้ว่าจะเป็น ES7, ES8 และ ESXXXXX __(ถ้ามีต่อนะ)__ มันก็คือการอัพเดตซอฟต์แวร์ อะไรประมาณนี้

-* API ที่ใช้ติดต่อกับ DOM หรือใช้งานร่วมกับ HTML5, CSS3 ใน ES6 เขาไม่ได้เปลี่ยนแปลงอะไรเลย
+* API ที่ใช้ติดต่อกับ DOM หรือใช้งานร่วมกับ HTML5.1, CSS3 ใน ES6 เขาไม่ได้เปลี่ยนแปลงอะไรเลย
-* ES6, ES7, ES8 มันเป็นแค่มาตรฐานใหม่สด ๆ ซิง ๆ ดังนั้นการใช้งานโดยตรงบนเว็บบราวเซอร์ (ปัจจุบันที่ผมเขียนอยู่นี้) ก็ยังไม่ support ทุกฟีเจอร์ ต้องมีตัวคอมไพล์ช่วยก่อน (ยังมีข้อจำกัดบางประการ) …แต่ถ้าใครใช้ Node.js เวอร์ชั่น 7 ขึ้นไป (ยังไม่ปล่อยออกมา) ถึงจะรองรับ ES6 ได้ 100% (ES7 รองรับได้บางส่วน)
+* ES6, ES7, ES8 มันเป็นแค่มาตรฐานใหม่สด ๆ ซิง ๆ ดังนั้นการใช้งานโดยตรงบนเว็บบราวเซอร์ (ปัจจุบันที่ผมเขียนอยู่นี้) ก็ยังไม่ support ทุกฟีเจอร์ ต้องมีตัวคอมไพล์ช่วยก่อน (ยังมีข้อจำกัดบางประการ) …แต่ถ้าใครใช้ Node.js เวอร์ชั่น 7 ก็จะรองรับ ES6 ได้ 99%

@@ -97,10 +59,21 @@

-### เครื่องมือในการพัฒนาจาวาสคริปต์
+### ลองมาดูความนิยมของ ES6 กัน
+
+
+
+จากรูปเป็นผลสำรวจปี 2016 จะเห็นว่ามาตรฐานใหม่ ES6 คนเริ่มใช้งานเยอะ ไล่จี้จาวาสคริปต์แบบเก่าติดๆ แล้ว (ES5)
+
+(ที่มา http://stateofjs.com/2016/flavors/)
+
+### เครื่องมือในการพัฒนาจาวาสคริปต์ (IDE)
-* มีให้ใช้ฟรีหลายตัวมาก เช่น Sublime Text, Atom, Free JavaScript Editor, Aptana Studio, NetBeans, Eclipse ฯลฯ
-* หรือแม้แต่ใช้อิดิเตอร์ธรรมดา เช่น Notepad, Notepad++ และ EditPlus เป็นต้น
+* มีให้ใช้ฟรีหลายตัวมาก เช่น Visual Studio Code, Sublime Text, Atom, Free JavaScript Editor, Aptana Studio, NetBeans, Eclipse ฯลฯ
+* หรือแม้แต่ใช้อิดิเตอร์ (Editor) ธรรมดา เช่น Notepad, Notepad++ และ EditPlus เป็นต้น
+* หรือถ้าเป็น geek หน่อย ก็จะใช้ Text Editor อย่าง Vim, Emacs เป็นต้น
+
+
### Node.js มันคืออะไรตับไตใส้พุง?
@@ -121,14 +94,10 @@

-ถ้าใครขี้เกียจสมัครเป็นสมัครชิก ก็ให้ใช้ลิงค์ดังต่อไปนี้แทน
-
-* http://www.ebooks.in.th/ebook/37385/วิธีติดตั้ง_Node.js_และ_npm_เบื้องต้น/
-* http://www.ebooks.in.th/ebook/37714/เสียดายไม่ได้อ่าน_จาวาสคริปต์ฝั่งเซิร์ฟเวอร์_Node.js_(ฉบับย่อ)/
-* http://www.ebooks.in.th/ebook/37836/เสียดายไม่ได้อ่าน_จาวาสคริปต์ฝั่งเซิร์ฟเวอร์_Node.js_ฉบับย่อ_เล่ม2/
-* http://www.ebooks.in.th/ebook/37861/การใช้งาน_MongoDB_เบื้องต้น/
* เล่มอื่นเผื่อใครสนใจ http://www.ebooks.in.th/adminho/
+
+
### ตัวอย่างจาวาสคริปต์บนเว็บเบราเซอร์
ตัวอย่างต่อไปนี้จะแสดงการเขียนจาวาสคริปต์ตามมาตรฐานเก่า ES5 ซึ่งจะต้องแทรกอยู่ภายใต้แท็ก < script > ...< /script > ของไฟล์ HTML โดยทั้งนี้จะสมมติว่าบันทึกเป็นไฟล์ index.html
@@ -199,7 +168,9 @@ C:\ES6>
### ตัวอย่างการเขียน ES6 กับ ES7 บนเว็บเบราเซอร์
-เนื่องจากตอนที่ผู้เขียนแต่งหนังสือ มาตรฐาน ES6 เพิ่งออกมาใหม่ และเว็บเบราเซอร์ส่วนใหญ่จะใช้งานได้กับ ES5 ด้วยเหตุนี้จึงต้องนำซอร์สโค้ดที่เขียนด้วย ES6 มาคอมไพล์ ด้วยคอมไพเลอร์ที่เรียกว่า “transpiler” เพื่อแปลงจาก ES6 ให้กลายมาเป็นเวอร์ชั่น ES5 ที่เว็บเบราเซอร์ส่วนใหญ่ใช้งานได้ไปก่อน
+เนื่องจากเว็บเบราเซอร์ส่วนใหญ่จะใช้งานได้กับ ES5 ด้วยเหตุนี้จึงต้องนำซอร์สโค้ดที่เขียนด้วย ES6 มาคอมไพล์ ด้วยคอมไพเลอร์ที่เรียกว่า “transpiler” เพื่อแปลงจาก ES6 ให้กลายมาเป็นเวอร์ชั่น ES5 ที่เว็บเบราเซอร์ส่วนใหญ่ใช้งานได้ไปก่อน
+
+#### Traceur
โดยตัวอย่างต่อไปนี้จะแสดงการเขียนจาวาสคริปต์บนเว็บเบราเซอร์ โดยใช้ Traceur ทำตัวเป็น transpiler (อย่าเพิ่งสนใจรายละเอียดซอร์สโค้ดที่ยกมาให้ดูนะครับ)
@@ -230,6 +201,7 @@ C:\ES6>
let chat = new Chat("Hello, world!"); // let ไวยากรณ์ใหม่ของ ES6
chat.say();
+ // ตัวอย่างโค้ด ES7 ชุดนี้ยังรันได้เฉพาะบน Google Chrome
let array = ["A", "B", "C"]; // let ไวยากรณ์ใหม่ของ ES6
console.log(array.includes("A")); // true -- เมธอดของอาร์เรย์ที่เพิ่มเข้ามาใน ES7
@@ -248,712 +220,470 @@ C:\ES6>

-*** Traceur ที่เห็นเป็นของ Google แต่ทั้งนี้ปัจจุบันตัว transpiler ก็มีหลายเจ้าให้เลือก (ผมแสดงให้ดูแค่เจ้าเดียวครับ) ซึ่งเท่าที่ผมลองใช้งานดูหลายเจ้า มันก็ยังไม่นิ่งเท่าไร ถ้าจะนำมันไปใช้งานยังไง ก็ควรหมั่นอัพเดตจากทีมสร้างเขาอีกทีนะครับ ...ที่สำคัญวิธีใช้งานแต่ละเจ้า ก็ดันแตกต่างกันอีกแฮะ!
-จนหนังสือที่ผมเขียนไป ถ้าใครลองทำตาม แล้วใช้งาน ES6 ไม่ได้ เค้าขอโทษแล้วกันน๊า! ยังไงเดี่ยวขออัพเดตโค้ดล่าสุดที่เว็บนี้แล้วกันเนอะ
+สังเกตในโค้ดจะต้องระบุ < script type="module" >
-### ตัวอย่างการเขียน ES6 กับ ES7 บน Node.js
-
-ต่อไปจะแสดงการเขียนจาวาสคริปต์ด้วย ES6 กับ ES7 แล้วสั่งรันผ่านทาง Node.js โดยตรง ไม่ต้องใช้ transpiler (หรือจะใช้ ก็แล้วแต่ครับ)
+แต่ถ้าจะเขียนโค้ดจาวาสคริปต์ แยกออกมาเป็นไฟล์ .js เช่น mylib.js ก็สามารถทำได้ โดยจะมีโครงสร้างข้างล่าง
-*** ทั้งนี้ Node.js ตอนที่ผมเขียนหนังสือ มันรองรับ ES6 ได้แค่ 93 % (เศร้ากันไหม?)
+```js
+C:\ES6>
+ |-- index.html
+ |-- mylib.js
+```
-*** ส่วน ES7 ก็ยังรองรับได้ไม่เต็มที่
+ส่วนไฟล์ mylib.js ก็หน้าตาแบบนี้ไง แค่แยกโค้ดจาวาสคริปต์ออกมา
```js
-class Chat{ // class ไวยากรณ์ใหม่ของ ES6
- constructor(message) { // constructor ไวยากรณ์ใหม่ของ ES6
+class Chat{ // class ไวยากรณ์ใหม่ของ ES6
+ constructor(message) { // constructor ไวยากรณ์ใหม่ของ ES6
this.message = message;
}
say(){
- console.log(this.message);
+ let element = document.querySelector('#element1');
+ element.innerHTML = this.message;
}
}
let chat = new Chat("Hello, world!"); // let ไวยากรณ์ใหม่ของ ES6
-chat.say(); // "Hello, world!"
+chat.say();
-let array = ["A", "B", "C"];
-console.log(array.includes("A")); // true -- เมธอดของอาร์เรย์ที่เพิ่มมาใน ES7
+// ตัวอย่างโค้ด ES7 ชุดนี้ยังรันได้เฉพาะบน Google Chrome
+let array = ["A", "B", "C"]; // let ไวยากรณ์ใหม่ของ ES6
+console.log(array.includes("A")); // true -- เมธอดของอาร์เรย์ที่เพิ่มเข้ามาใน ES7
```
-จะสมมติว่าบันทึกเป็นไฟล์ test.js โดยมีโครงสร้างโปรเจคดังนี้
+สามารถเขียนอ้างไฟล์ .js ได้ง่ายๆ ดังนี้
```js
-C:\ES6>
- |-- test.js
-```
-
-รันไฟล์ test.js ผ่านทาง Node.js ด้วยความสั่งต่อไปนี้ ตามรูป
-
-
-
-## บทที่ 2 ทวน ES5 (มาตรฐานเก่า)
+
+
+
+
-(บทนี้ ยังไม่เสร็จดีครับ)
+
+
+
+
-### Comments
+
+
+
-คอมเมนต์ในจาวาสคริปต์ ก็จะเหมือนภาษาที่มีรากฐานมาจากภาษา C โดยจะใช้เครื่องหมาย // นำหน้าประโยคที่ต้องการคอมเมนต์ได้เพียงบรรทัดเดียวเท่านั้น
+
-```js
-var x = 10; //This is an example.
+
+
```
-แต่ถ้าต้องการคอมเมนต์หลายๆ บรรทัด ก็ให้ใช้เครื่องหมาย /*… */ มาครอบเปิดและปิดท้าย กลุ่มประโยคที่ต้องการ
-```js
-/* This is an example
-ECMAScript 6 is very easy*/
-```
-### console.log
+**หมายเหต** วิธีอิมพอร์ตไฟล์ด้วยวิธีนี้ ถ้าไปเปิดดูบน Google Chrome อาจไม่ทำงาน แต่ไม่ต้องซีเรียส เรามีทางแก้ไข แนะนำให้ไปอ่านหัวข้อ [Cross-origin resource sharing (CORS)] (#cross-origin-resource-sharing-cors)
+
+#### Babel
-ประโยคคำสั่ง console.log() จะเป็นฟังก์ชั่น (Function) ในจาวาสคริปต์ ที่ใช้ประโยชน์ในแง่ของการดีบั๊ก (Debug) เพื่อแสดงข้อความออกทางหน้าคอนโซล (Console)
+ต่อไปจะแสดงการเขียนจาวาสคริปต์บนเว็บเบราเซอร์ โดยใช้ Babel ทำตัวเป็น transpiler (ผลการทำงานจะเหมือนตัวอย่างตอนใช้ Traceur )
```js
+
-
+
+
+
+
+
- Hello, world!
-
+
+
```
-จะปรากฏผลลัพธ์ดังนี้
-
-
-
-### Semicolon
-
-จาวาสคริปต์ถือว่าเป็นภาษาหนึ่ง ที่ไม่ต้องใช้เครื่องหมายเซมิโคลอน (;) ต่อท้ายแต่ละประโยคคำสั่งก็ได้ ดังตัวอย่าง
-
-```js
-// ไม่ต้องมี ; ต่อท้ายประโยคก็ได้
-console.log("Hello world")
-
-// หรือมี ; ต่อท้ายประโยคก็ได้
-console.log("Hello world");
-```
-
-แต่ถ้ามี 2 ประโยคคำสั่งขึ้นไป เขียนติดกันอยู่ภายในบรรทัดเดียวกัน จะต้องมี ; แบ่งคันเอาไว้เสมอ
+จะสมมติว่าบันทึกเป็นไฟล์ index.html โดยมีโครงสร้างโปรเจคดังนี้
```js
-// แบบนี้จะเกิด Syntax Error เพราะไม่มี ; แบ่งคั่นประโยค
-// console.log("Hello, world!") console.log("Hello, world!");
-
-console.log("Hello, world!") ; console.log("Hello, world!")
-// Hello, world!
-// Hello, world!
+C:\ES6>
+ |-- index.html
```
-แต่ทั้งนี้เขาจะนิยมใส่ ; ต่อท้ายประโยคเหมือนหลายๆ ภาษา
-
+เมื่อดับเบิลคลิกที่ไฟล์ index.html จะปรากฏตามรูป
-### การประกาศตัวแปร
+
-การประกาศตัวแปร จะใช้คีย์เวิร์ด var นำหน้าชื่อตัวแปร ดังตัวอย่าง
+สังเกตในโค้ดจะต้องระบุ < script type="text/babel" > หรือเขียนเป็น < script type="text/jsx" > ก็ได้เหมือนกัน
-```js
-var x = 100;
-```
+แต่ถ้าจะเขียนโค้ดจาวาสคริปต์ แยกออกมาเป็นไฟล์ .js เช่น mylib.js ก็สามารถทำได้ โดยจะมีโครงสร้างข้างล่าง (ไฟล์ .js หน้าตาเหมือนตอนใช้ Traceur)
-หรือจะประกาศตัวแปรให้อยู่ในบรรทัดเดียวกันก็ได้ ดังตัวอย่าง
```js
-var x = 1, y = 2, z = 3; // ประกาศตัวแปร x, y และ z ให้อยู่ในบรรทัดเดียวกัน
+C:\ES6>
+ |-- index.html
+ |-- mylib.js
```
-แต่ถ้าเราไม่ได้กำหนดค่าเริ่มต้นให้กับตัวแปร ตอนประกาศตัวแปร ก็จะมีค่าเป็น undefined ดังตัวอย่าง
+สามารถเขียนอ้างไฟล์ .js ได้ง่ายๆ ดังนี้ (สังเกตโค้ดดีๆ วิธีอิมพอร์ตไฟล์ .js จะต่างกับ Traceur เล็กน้อย)
```js
-var x;
-console.log(x); // undefined
-```
-### Literals
-สำหรับข้อมูล (Literals) ที่สามารถกำหนดค่าให้กับตัวแปรได้นั้น ในจาวาสคริปต์ก็จะมีหลากหลายชนิดข้อมูล แต่โดยหลัก ๆ จะมีอยู่ 2 แบบได้แก่
-
-* ข้อมูลพื้นฐาน (Primitives data)
-* อ็อบเจ็กต์ (Object)
+
+
+
+
-สำหรับข้อมูลพื้นฐาน จะแยกย่อยได้นี้
+
+
-* null
-* undefined
-* ตัวเลข (Number)
-* สตริง (String) รวมทั้งเทมเพลตสตริง (Template String)
-* บูลีน (Boolean)
-* ซิมโบล (Symbol)
+
+
+
+
+
+
+```
-### Function
+**หมายเหต** วิธีอิมพอร์ตไฟล์ด้วยวิธีนี้ ถ้าไปเปิดดูบน Google Chrome อาจไม่ทำงาน แต่ไม่ต้องซีเรียส เรามีทางแก้ไข แนะนำให้ไปอ่านหัวข้อ [Cross-origin resource sharing (CORS)] (#cross-origin-resource-sharing-cors)
-ตัวอย่างต่อไปนี้จะเป็นการประกาศฟังก์ชั่น
+### โหลดไฟล์ Traceur กับ Babel มาเก็บไว้ที่เครื่องแบบออฟไลน์
-```js
-function calculate(param1, param2){
- return param1 * param2;
-}
-```
+#### Traceur แบบออฟไลน์
-ส่วนวิธีเรียกใช้งานฟังก์ชั่น ก็จะเหมือนกับภาษาเขียนโปรแกรมทั่ว ๆ ไป ดังตัวอย่าง
+จากตัวอย่างก่อนๆ เวลาเขียน ES6 กับ ES7 บนว็บบราวเซอร์ด้วย Traceur ผมต้องอ้างถึงไฟล์ traceur.js, BrowserSystem.js และ bootstrap.js แบบออนไลน์ แต่ถ้าจะโหลดไฟล์นี้ (ทั้งหมดที่เกี่ยวข้อง) มาเก็บไว้ที่เครื่องแบบออฟไลน์ ก็ให้ใช้คำสั่ง npm ข้างล่าง (วิธีติดตั้งและใช้งาน npm ก็ตามหนังสือข้างบนที่แจกให้อ่านฟรี)
```js
-var result = calculate(10, 2);
-console.log(result); // 20
+C:\ES6>npm install -save traceur
```
-### Hoist
-
-การประกาศฟังก์ชั่น รวมทั้งการประกาศตัวแปรแบบ var มันจะลอยขึ้นไปประกาศอยู่ข้างบนสุดของขอบเขตการมองเห็น ดังตัวอย่าง
+จะเห็นไฟล์ถูกโหลดเข้ามาเก็บ ได้แก่ traceur.js กับ BrowserSystem.js
```js
-function myFunction(num){
- // สามารถมองเห็นตัวแปร value
- console.log(value); // undefined
-
- if(num > 10) {
- var value = num*10; // ประกาศตัวแปร value ที่ตรงนี้ แต่มองเห็นได้ทั่วฟังก์ชั่น
-
- /* ซอร์สโค้ด */
-
- } else {
-
- // ถ้าเงื่อนไขประโยค if เป็นเท็จ ก็จะเข้ามาทำงานที่ else
- // ซึ่งจะเห็นตัวแปร value มีค่าเป็น undefined
-
- console.log(value); // undefined
- }
-
- // สามารถมองเห็นตัวแปร value ได้ หลังจากประโยค if …else ทำงานเสร็จสิ้น
- console.log(value);
-}
+C:\ES6\node_modules\traceur\bin
+ |-- BrowserSystem.js
+ |-- traceur.js
```
-จากตัวอย่างซอร์โค้ดดังกล่าวที่ยกมาให้ดู จริง ๆ แล้ว จาวาสคริปต์จะทำการแปลงซอร์สโค้ดให้มีหน้าตาดังต่อไปนี้
+ส่วนไฟล์ bootstrap.js ก็จะอยู่ที่
```js
-function myFunction(num){
- var value; // ประกาศตัวแปร value โดยไม่มีค่าเริ่มต้น จึงทำให้มีค่าเป็น undefined
- console.log(value); // undefined
-
- if(num > 10) {
- value = num*10; // บรรทัดนี้เป็นเพียงการกำหนดค่าให้กับตัวแปร value
-
- /* ซอร์สโค้ด */
- } else {
-
- console.log(value); // undefined
-
- }
-
- console.log(value);
-}
+C:\ES6\node_modules\traceur\src
+ |-- bootstrap.js
```
-(บทนี้ ยังไม่เสร็จดีครับ)
-
-
-## บทที่ 3 แนะนำ ES6
-
-(บทนี้ ยังไม่เสร็จดีครับ)
-
-### 3.1 การประกาศตัวแปร และการกำหนดค่า
+#### Babel แบบออฟไลน์
-#### การประกาศตัวแปรแบบ let
-
-การประกาศตัวแปรแบบ var จะถูกลอยขึ้นไปประกาศอยู่ด้านบนสุด (hoist)
-
-แต่การใช้ let ในการประกาศตัวแปร ขอบเขตการมองเห็นเริ่มตั้งแต่จุดที่ประกาศใช้งานภายในบล็อก (ไม่ลอยขึ้นไปอยู่บนสุด หรือ hoist) ส่วนตัวแปรก็จะมีชีวิตอยู่ภายในบล็อกปัจจุบัน ดังตัวอย่าง
+สำหรับ Babel ก็เช่นกัน สามารถโหลดไฟล์ babel.js หรือ babel.min.js มาใช้แบบออฟไลน์ (เลือกใช้ไฟล์ไหนก็ได้) ด้วยคำสั่ง npm ดังนี้
```js
-function calculate(num){
- if (num > 10) {
- let value = num*10; // ประกาศตัวแปรแบบ let
-
- // ซอร์สโค้ดส่วนที่เหลือ
- console.log(value); // มองเห็นตัวแปร value
- } else {
-
- // มองไม่เห็นตัวแปร value
-
- }
-
- // มองไม่เห็นตัวแปร value
-}
+C:\ES6>npm install --save babel-standalone
```
-#### ตัวแปรค่าคงที่
-
-การประกาศตัวแปรค่าคงที่ (Constants) จะใช้คีย์เวิร์ด const นำหน้าชื่อตัวแปร
-แต่เราต้องกำหนดให้มันมีค่าเริ่มต้น ตั้งแต่ประกาศตัวแปรครั้งแรก และหลังจากนั้นก็ห้ามไปแก้ไขค่าอะไรภายหลังเด็ดขาด มิฉะนั้นจะเกิด error ดังตัวอย่าง
+จะเห็นไฟล์ถูกโหลดมาเก็บตามนี้
```js
-const MAX_COUNT = 100; // ประกาศถูกต้องตามไวยากรณ์
-const MAX_VALUE; // เกิด error เพราะไม่ได้กำหนดค่าตั้งต้นให้แต่แรก
-const MESSAGE = "Hello"; // ประกาศถูกต้องตามไวยากรณ์
-MESSAGE = "Bye"; // เกิด error เพราะไปแก้ไขตัวแปรค่าคงที่ภายหลังประกาศใช้งานแล้ว ซึ่งจะทำไม่ได้
+C:\ES6\node_modules\babel-standalone
+ |-- babel.js
+ |-- babel.min.js
```
-(เดี่ยวมาเขียนต่อให้เสร็จ)
+หรือไปที่เว็บข้างล่างแล้วเลือกโหลดไฟล์ทั้งสองนี้ก็ได้
-### 3.2 Functions
+https://github.com/Daniel15/babel-standalone/releases
-#### Arrow Functions
+*** Traceur กับ Babelเท่าที่ผมลองใช้งานดู มันยังไม่นิ่งเท่าไร ถ้าจะนำมันไปใช้งานยังไง ก็ควรหมั่นอัพเดตจากทีมสร้างเขาอีกทีนะครับ ...ที่สำคัญวิธีใช้งานแต่ละเจ้า ก็ดันแตกต่างกันอีกแฮะ! จนหนังสือที่ผมเขียนไป ถ้าใครลองทำตาม แล้วใช้งาน ES6 ไม่ได้ เค้าขอโทษแล้วกันน๊า! ยังไงเดี่ยวขออัพเดตโค้ดล่าสุดที่เว็บนี้แล้วกันเนอะ
-ในหลาย ๆ ภาษาจะมี "Lambda expressions" ซึ่งคนที่มาจากภาษาอื่นอาจรู้จักกันดีอยู่แล้ว เช่น ใน C# จะใช้สัญลักษณ์ => หรือถ้าเป็นจาวา (ตั้งแต่ Java 8) จะใช้สัญลักษณ์ ->
+### วิธีคอมไพล์จาก ES6 ให้เป็น ES5 ด้วยมือตนเอง
-แต่สำหรับจาวาสคริปต์จะเรียกว่า "Arrow Functions" แปลตรงตัวก็คือ "ฟังก์ชั่นลูกศร" โดยใช้เครื่องหมาย => (มันคือฟังก์ชั่นไร้ชื่อ ที่ไม่ได้ใช้คีย์เวิร์ด function) ซึ่งมันเขียนได้หลายวิธีมากๆ ดังตัวอย่างต่อไปนี้
+#### Traceur
-
-##### ตัวอย่างที่ 1
+เราสามารถใช้กระบวนท่าแปลงซอร์สโค้ดจาก ES6 เป็น ES5 ด้วยมือตนเอง ด้วยการเปิดคอมมานไลน์ขึ้นมา (ตัวอย่างจะใช้วินโดวส์) แล้วเรียกสคริปต์ traceur ซึ่งถ้าคุณทำตามตัวอย่างก่อนหน้า ที่แนะวิธีโหลดไฟล์ Traceur มาเก็บแบบออฟไลน์ ด้วยคำสั่ง npm install -save traceur ก็ให้ไปที่โฟลเดอร์ ...\node_modules\ .bin จะเห็นไฟล์สคริปดังนี้
```js
-let arrowFunc = function(value){
- return value;
-};
-
-console.log(arrowFunc(122)); // 122
+C:\ES6\node_modules\.bin
+ |-- traceur
+ |-- traceur.cmd
```
-จากตัวอย่างดังกล่าว สามารถเปลี่ยนมาเขียนแบบฟังก์ชั่นลูกศร ได้ดังนี้
+จากไฟล์ mylib.js ในตัวอย่างก่อนหน้านี้ (โค้ด ES6)
```js
-let arrowFunc = value => {
- return value;
-};
-
-// เรียกใช้ฟังก์ชั่นได้เหมือนปกติธรรมดา
-console.log(arrowFunc(122)); // 122
-```
-##### ตัวอย่างที่ 2
-
-```js
-// เหมือนในตัวอย่างที่ 1 แต่การเขียนจะสั้นและกระชับกว่า
-// ไม่ต้องมีเครื่องหมายปีกกา {....} ครอบบอดี้ฟังก์ชั่น รวมทั้งไม่ต้องเขียนประโยคคำสั่ง return
-let arrowFunc = value => value;
-console.log(arrowFunc(122)); // 122
+C:\ES6>
+ |-- index.html
+ |-- mylib.js
```
-จะเสมือนเขียนเป็น
+เราก็สามารถเรียกสคริปต์ traceur ให้มาทำการคอมไฟล์ mylib.js เพื่อแปลงเป็น ES5 ได้คำสั่งดังนี้
-```js
-let arrowFunc = function(value){
- return value;
-};
+```js
+C:\ES6\node_modules\.bin>traceur --out ../../out/mylib.js --script ../../mylib.js
```
+(ถ้าติดตั้ง Traceur ด้วยคำสั่ง npm install -g traceur ก็ไม่ต้อง cd มาที่ C:\ES6\node_modules\ .bin)
-อีกตัวอย่างหนึ่ง
+สำหรับไฟล์ที่ถูกแปลงเป็น ES5 จะเก็บอยู่ที่โฟลเดอร์ out\mylib.js
```js
-let arrowFunc2 = value => console.log(value);
-arrowFunc2(122); // 122
-```
+C:\ES6>
+ |-- index.html
+ |-- mylib.js
+ |-- out
+ |-- mylib.js
+```
-จะเสมือนเขียนเป็น
+ถ้าแอบไปเปิดไฟล์ out\mylib.js ก็จะเห็นว่าโค้ดถูกแปลงเป็น ES5 หน้าตาเรียบร้อยดังนี้
```js
-let arrowFunc2 = function(value){
- return console.log(value);
-};
+var Chat = function() {
+ "use strict";
+ function Chat(message) {
+ this.message = message;
+ }
+ return ($traceurRuntime.createClass)(Chat, {say: function() {
+ var element = document.querySelector('#element1');
+ element.innerHTML = this.message;
+ }}, {});
+}();
+var chat = new Chat("Hello, world!");
+chat.say();
+var array = ["A", "B", "C"];
+console.log(array.includes("A"));
```
-##### ตัวอย่างที่ 3
+จากตัวอย่างเดิม ก็สามารถเขียนใหม่ได้ดังนี้
```js
-// ฟังก์ชั่นลูกศรที่ไม่มีการประกาศพารามิเตอร์อะไรเลย
-let arrowFunc = () => 122;
-console.log(arrowFunc()); // 122
-```
+
+
+
+
-จะเสมือนเขียนเป็น
+
+
-```js
-let arrowFunc = function(){
- return 122;
-};
-```
-
-##### ตัวอย่างที่ 4
+
-```js
-// ฟังก์ชั่นลูกศรที่ไม่มีพารามิเตอร์ และตัวบอดี้ของฟังก์ชั่นก็ว่างเปล่า
-let arrowFunc = () => {};
-arrowFunc();
-```
+
+
-จะเสมือนเขียนเป็น
+
+
-```js
-var arrowFunc = function(){};
+
+
```
-##### ตัวอย่างที่ 5
+ซึ่งผลการทำงานจะเหมือนกับตัวอย่างก่อนๆ ที่ยกมา
-```js
-// ใส่เครื่องหมายวงเล็บ เพื่อครอบอ็อบเจ็กต์ที่ถูกรีเทิร์นออกมา
-let getFont = () => ( { color: "red", size: 200 } );
-console.log(getFont()); // {color: "red", size: 200}
-```
+#### Babel
-จะเสมือนเขียนเป็น
+สำหรับ Babel ก็เช่นกัน สามารถใช้กระบวนท่าแปลงซอร์สโค้ดจาก ES6 ให้เป็น ES5 ด้วยมือตนเอง โดยทำตามตัวอย่างจากเว็บต้นทางผู้สร้าง เขาจะแนะนำตามนี้
```js
-let getFont = function(){
- return {color: "red", size: 200};
-};
+var input = 'const getMessage = () => "Hello World";';
+var output = Babel.transform(input, { presets: ['es2015'] }).code;
```
-##### ตัวอย่างที่ 6
+จากตัวอย่างเดิม ก็สามารถเขียนใหม่ได้ดังนี้
```js
-// มีวงเล็บครอบพารามิเตอร์เอาไว้
-let sum = (val1, val2, val3) => val1 + val2 + val3;
-console.log(sum(1,2,3)); // 6
-```
-
-จะเสมือนเขียนเป็น
-
-```js
-let sum = function(val1, val2, val3){
- return val1 + val2 +val3;
-};
-```
-
-##### ตัวอย่างที่ 7
+
+
+
+
-```js
-// ฟังก์ชั่นลูกศรที่ใช้พารามิเตอร์แบบดีฟอลต์
-let sum = (val1 = 1, val2 = 2, val3 = 3) => val1 + val2 + val3;
-console.log(sum()); // 6
-```
+
+
-จะเสมือนเขียนเป็น
+
+
+
+
+
+
```
-จะเสมือนเขียน
+ซึ่งผลการทำงานจะเหมือนกับตัวอย่างก่อนๆ ที่ยกมา
-```js
-let max = function(...value){ // พารามิเตอร์แบบเรสต์
- return Math.max(...value); // โอเปอเรเตอร์สเปรด
-};
-```
+### Cross-origin resource sharing (CORS)
-(ยังเขียนไม่เสร็จดี)
+โดยปกติแล้วเว็บเพจ จะไม่สามารถแชร์ resources ข้าม domain กันได้ (เช่น ฟอนต์, ไฟล์จาวาสคริปต์ และรูปภาพ เป็นต้น) เพราะมันเป็นเรื่องของความปลอภัย (same-origin policy)
-### 3.3 Template strings
+คราวนี้ถ้าเขียนจาวาสคริปต์แบบแยกไฟล์ .js แล้วอิมพอร์ตเข้ามา (จากตัวอย่างก่อนหน้านี้ ผมอิมพอร์ตไฟล์ mylib.js เข้ามา ด้วยวิธี Traceur หรือ Babel) เมื่อนำไปเปิดบน Google Chrome อาจทำงานไม่ได้ (ซวยแล้วไง!) เพราะเมื่อไปดูที่ console จะเห็นมันฟ้องเรื่อง Cross origin ดังรูป
-เทมเพลตสตริง (Template strings) จะใช้เครื่องหมาย back-tick (ตัวอักษร grave accent) มาครอบข้อความเอาไว้ (เครื่องหมายจะคล้ายๆ กับคำพูดเดี่ยว แต่มันจะเอนไปด้านหน้าเล็กน้อย) ดังตัวอย่าง
+
-```js
-let msg = `JavaScript`;
+แต่เราสามารถหลีกเลี่ยงกฏข้อนี้ได้ โดยใช้ Cross-origin resource sharing (CORS) ซึ่งเป็นกลไกอนุญาตให้ resources บนเว็บเพจ ถูกเข้าถึงจาก Domain อื่นได้
-console.log(msg); // "JavaScript"
-console.log(msg.length); // 10
-console.log(typeof msg); // "string"
-```
-#### เขียนสตริงหลายบรรทัด
+**วิธีการแก้ปัญหา**
-เทมเพลตสตริงสามารถเขียนข้อความได้มากกว่า 1 บรรทัด (Multiline strings) ดังตัวอย่าง
+__วิธี1__
-```js
-let div = `
-
Hello world
-`;
+สามารถทำได้ง่ายๆ เพียงแค่บอกให้เว็บเซิร์ฟเวอร์ เพิ่มค่าต่อไปนี้ลงไปใน HTTP Header (วิธีกำหนดค่านี้ ต้องดูที่คู่มือของเซิร์ฟเวอร์แต่ละเจ้าเอาเอง)
-console.log(div);
+```js
+Access-Control-Allow-Origin: *
```
-แสดงผลลัพธ์เป็น
+จริงๆ ทำแบบนี้ก็ดูไม่ปลอดภัยเท่าไร ทางที่ดีควรให้สิทธิเฉพาะ url เท่าที่จำเป็น ตัวอย่างเช่น
```js
-
-
Hello world
-
+Access-Control-Allow-Origin: http://www.example.com http://test.example.com
```
-#### นิพจน์ในเทมเพลตสตริง
-ปกติแล้วการเขียนนิพจน์ร่วมกับสตริงแบบเดิมจะดูยุ่งยากมาก เพราะต้องใช้เครื่องหมายบวก (+) เชื่อมสตริงกับนิพจน์ต่าง ๆ เข้าด้วยกัน ดังตัวอย่าง
+(ที่มา http://manit-tree.blogspot.com/2012/07/cross-origin-resource-sharing.html)
-```js
-let a = 5, b = 10, c = 100;
-console.log("Price $" + ((a*b).toFixed(2)) + ", not " + (c + a) ); // "Price $50.00, not 105"
-```
+__วิธีที่ 2__
-แต่ถ้าลองเปลี่ยนมาใช้เทมเพลตสตริง ก็สามารถยัดนิพจน์เข้าไปอยู่ในสตริงได้เลย ดังตัวอย่าง
+ถ้าเราไม่ได้เขียนเว็บ แล้วเทสบนเว็บเซิร์ฟเวอร์ อารมณ์ทดสอบเว็บบนเครื่องตัวเองแบบ local ก็ต้องเปิด Google chrome ด้วยท่าพิศดาร โดยปลดความปลอดภัยเรื่องนี้ออก เพื่อให้มันทำ CORS ได้
-```js
-let a = 5, b = 10, c = 100;
+บนวินโดวส์ก็ให้ไปที่คอมมานไลน์ แล้วพิมพ์คำสั่งตามนี้ เมื่อนั้น Google Chrome ก็จะเปิดขึ้นมา แล้วถึงเปิดไฟล์ HTML ตามทีหลัง
-console.log(`Price $${(a*b).toFixed(2)}, not ${c + a}` ); // "Price $50.00, not 105"
+```js
+chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
```
-### 3.4 Symbols
-
-(เดี่ยวมาเขียน)
-
-### 3.5 Objects
-
-(เดี่ยวมาเขียน)
-
-### 3.6 คลาส
-
-คลาสใน ES6 จะเหมือนกับภาษาโปรแกรมเชิงวัตถุอื่น ๆ (OOP: Object Oriented Programming) ที่เปรียบได้เป็นพิมพ์เขียวเอาไว้สร้างอ็อบเจ็กต์ โดยตัวอย่างต่อไปนี้จะแสดงการประกาศคลาส Car ขึ้้นมา (ยังไม่มีสมาชิกอะไรอยู่ข้างใน)
+หรือจะระบุชื่อไฟล์ HTML ให้เปิดขึ้นมาพร้อมกับ Google Chrome ก็ได้
+```js
+chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security "c:\ES6\index.html"
-```js
-class Car {
- // สมาชิกภายในคลาส ยังไม่ได้ประกาศ
-}
```
-มันก็เหมือนๆ ภาษาอื่น เราสามารถใช้โอเปอเรอตร์ new สร้างอ็อบเจ็กต์จากคลาส Car ข้างต้นขึ้นมาได้
+อีกวิธีหนึ่งง่ายดี ให้ไปที่ Shortcut ของ Google Chrome แล้วคลิกขวาเปิดมันขึ้นมา จากนั้นจึงเพิ่มค่าต่อไปนี้ตรงช่อง "Target:" หลังข้อความเดิม
-```js
-let car1 = new Car();
-let car2 = new Car();
-let car3 = new Car();
+```js
+--user-data-dir="C:/Chrome dev session" --disable-web-security
```
-#### สมาชิกคลาส
+
-ในคลาสสามารถมีสมาชิกดังต่อไปนี้
+ต่อไปนี้ ก็ให้เปิดที่ Shortcut ของ Google Chrome ก่อนเสมอ แล้วหลังจากนั้น จึงเปิดไฟล์ HTML ตามทีหลัง
-1) สมาชิกที่เป็นคอนสตรัคเตอร์ (constructor) โดยใช้เมธอดที่ชื่อ constructor ทำหน้าที่เป็นคอนสตรัคเตอร์เหมือนในภาษา OOP อื่นๆ
-2) สมาชิกที่เป็นเมธอด
+ส่วนบน OSX กับ Linux ผมไม่มีเครื่องลองครับ จึงไม่กล้าเขียน ลองดูเพิ่มเติมได้ที่
-*** ทั้งนี้สมาชิกของคลาส ไม่ว่าจะเป็นคอนสตรัคเตอร์ และเมธอดต่างๆ ไม่ต้องใช้เครื่องหมายจุลภาค , แบ่งคั่นนะ
+http://stackoverflow.com/questions/3102819/disable-same-origin-policy-in-chrome
-```js
-class Car {
- constructor(param){ // ประกาศคอนสตรัคเตอร์
- console.log(param);
- }
-
- drive(){ // ประกาศเมธอด
- console.log("The car is running");
- }
-}
-
-let carObj = new Car("red"); // "red"
-carObj.drive(); // "The car is running"
-```
-มีข้อสังเกต ในภาษา C++, Java, C# สามารถประกาศตัวแปรเป็นสมาชิกประเภทหนึ่งในคลาสได้
-แต่เสียใจด้วยใน ES6 ไม่สามารถประกาศตัวแปร เป็นสมาชิกในคลาสได้ ...เว้นแต่ใช้ภาษา TypeScript เราก็สามารถประกาศได้
+__วิธีที่ 3__
-ถึงกระนั้นก็ดีสามารถประกาศพร็อพเพอร์ตี้ที่เป็นตัวแปรขึ้นมาได้ ด้วยการใช้ this.xxx ภายในคอนสตรัคเตอร์ ดังตัวอย่าง
-(ในเมธอดก็ประกาศได้ แต่อาจผิดหลักการ OOP ซึ่งคอนสตรัคเตอร์ ควรทำหน้าที่กำหนดค่าต่างๆ ให้กับพร็อพเพอร์ตี้ของอ็อบเจ็กต์)
+จากไฟล์ index.html ที่มีปัญหาเวลาเปิด Google Chrome แล้วไม่ทำงาน
```js
-class Car {
- constructor(param){
- this.param = param; // ประกาศพร็อพเพอร์ตี้ param ขึ้นมา (แต่เป็นของอ็อบเจ็กต์) แล้วกำหนดค่าให้มัน
- }
-
- drive(){
- console.log(`The ${this.param} car is running`);
- }
-}
-
-let carObj = new Car("red"); // "red"
-carObj.drive(); // "The red car is running"
+C:\ES6>
+ |-- index.html
+ |-- mylib.js
```
-#### เบื้องหลังของคลาส
-
-ให้ลองพิจารณาตัวอย่างต่อไปนี้ประกอบ
-
-```js
-class Car {
- constructor (speed){
- this.speed = speed;
- }
-
- drive(){
- console.log("Driving speed:", this.speed);
- }
-}
-
-let carObj = new Car(100);
-carObj.drive(); // "Driving speed: 100"
-```
-จากคลาส Car และ carObj ในตัวอย่าง ถ้าเราลองใช้ instanceof ตรวจสอบอ็อบเจ็กต์ carObj จะพบว่านอกจากมันเป็นอินสแตนซ์ของ Car แล้ว ยังเป็นอินสแตนซ์ของ Object อีกด้วย โดยจะให้ลองพิจารณาตัวอย่างต่อไนี้ประกอบ
+ให้ลองใช้เซิร์ฟเวอร์จำลอง จาก Node.js แต่ก่อนอื่นจะให้ติดตั้งเซิร์ฟเวอร์ที่ว่า ก็คือ live-server ด้วยคำสั่ง npm ดังนี้
```js
-console.log(typeof carObj); // "object"
-console.log(carObj instanceof Car); // true
-console.log(carObj instanceof Object); // true
+npm install -g live-server
```
-จริงๆ แล้วเมธอด drive() ของคลาส Car จะถูกประกาศไว้ที่ Car.prototype ส่วนคลาส Car จริงๆ ก็คือฟังก์ชั่นคอนสตรัคเตอร์ที่มีชื่อว่า "Car" นั่นเอง โดยจะให้ลองพิจารณาตัวอย่างต่อไนี้ประกอบ
+จากนั้นก็ cd ไปที่ C:\ES6\ ต่อด้วยสั่งให้ live-server ทำการรัน index.html ด้วยคำสั่งง่ายๆ ดังนี้
```js
-console.log(carObj.drive === Car.prototype.drive); // true
-console.log(typeof Car.prototype.drive); // "function"
-
-// คลาส Car ก็คือฟังก์ชั่นคอนสตรัคเตอร์ที่ชื่อ Car
-console.log(typeof Car); // "function"
-console.log(Car.name); // "Car"
-console.log(Car === Car.prototype.constructor); // true
-console.log(Car.prototype.constructor.name); // "Car"
+C:\ES6>live-server
```
-#### Property accessors
+เมื่อนั้นเว็บบราวเซอร์ที่ถูกตั้งไว้เป็นดีฟอลต์ ก็จะเด้งขึ้นมา และเปิดไฟล์ index.html อย่างอัตโนมัติ หรือถ้าเครื่องเรา Google Chrome ไม่ได้ตั้งเป็นดีฟอลต์ ก็ให้กรอก url ตรงๆ เป็น http://127.0.0.1:8080/ ตามรูป
-เราสามารถมีพร็อพเพอร์ตี้แอคเซสเซอร์ (Property accessors) หรือเมธอด getter กับ setter ในคลาส ดังตัวอย่าง
+
+
+** เสริมนิดหนึ่ง ถ้าใครใช้ Python ก็อาจใช้เซิร์ฟเวอร์จำลองได้ด้วยเช่นกัน อย่างกรณีผมใช้ Python 3 ก็จะพิมพ์คำสั่งดังนี้
```js
-class Car {
- constructor (){
- this.speedValue = 100;
- }
- get speed(){ // เมธอด getter
- return this.speedValue;
- }
- set speed(speedValue) { // เมธอด setter
- this.speedValue = speedValue;
- }
-}
+C:\ES6>python -m http.server 8080
+```
-let carObj = new Car(100);
-console.log(carObj.speed); // 100
+จากนั้นก็เปิด Google Chrome ขึ้นมาโดยกรอก url เป็น http://127.0.0.1:8080/
-carObj.speed = 60;
-console.log(carObj.speed); // 60
-console.log(carObj.speedValue); // 60 (่ไม่ควรเข้าถึงด้วยวิธีนี้โดยตรง ตามหลัก information hiding ของ OOP)
-```
-#### Static methods
+### ตัวอย่างการเขียน ES6 กับ ES7 บน Node.js
-เมธอดสแตติก (Static methods) คือเมธอดของคลาส ที่เวลาเรียกใช้งานจะต้องผ่านชื่อคลาสโดยตรง (ไม่ต้องเรียกผ่านอ็อบเจ็กต์ เพราะมันไม่ใช่เมธอดของอ็อบเจ็กต์)
+ต่อไปจะแสดงการเขียนจาวาสคริปต์ด้วย ES6 กับ ES7 แล้วสั่งรันผ่านทาง Node.js โดยตรง ไม่ต้องใช้ transpiler (หรือจะใช้ ก็แล้วแต่ครับ)
-โดยสามารถใช้คีย์เวิร์ด static นำหน้าชื่อเมธอด หรือพร็อพเพอร์ตี้แอคเซสเซอร์ก็ได้ แต่มีข้อแม้ว่าห้ามใช้คำว่า static นำหน้าคอนสตรัคเตอร์
+*** ทั้งนี้ Node.js เวอร์ชั่น 7 ขึ้นไปก็จะรองรับ ES6 ได้ 99%
```js
-class Car {
- constructor (speed){ // ห้ามมีคำว่า static นำหน้าคอนสตัคเตอร์
- this.speed = speed;
- }
- drive(){
- console.log("Driving speed:", this.speed);
-
+class Chat{ // class ไวยากรณ์ใหม่ของ ES6
+ constructor(message) { // constructor ไวยากรณ์ใหม่ของ ES6
+ this.message = message;
}
- static stop() { // เมธอดสแตติก
- console.log("Stop this car");
+ say(){
+ console.log(this.message);
}
-}
+}
-// เรียกใช้งานเมธอดสแตติกผ่านชื่อคลาส
-Car.stop(); // "Stop this car"
+let chat = new Chat("Hello, world!"); // let ไวยากรณ์ใหม่ของ ES6
+chat.say(); // "Hello, world!"
-let carObj = new Car(100);
-carObj.drive(); // "Driving speed: 100"
-console.log(typeof carObj.drive); // "function"
-console.log(typeof carObj.stop); // undefined
+let array = ["A", "B", "C"];
+console.log(array.includes("A")); // true -- เมธอดของอาร์เรย์ที่เพิ่มมาใน ES7
```
-#### Class Inheritance
-
-การสืบทอดคลาส (Class Inheritance) ในจาวาสคริปต์ สามารถทำได้โดยใช้คีย์เวิร์ด extends ดังตัวอย่าง
+จะสมมติว่าบันทึกเป็นไฟล์ test.js โดยมีโครงสร้างโปรเจคดังนี้
```js
-class Calculation {
- constructor (a, b){
- this.a = a;
- this.b = b;
- }
- multiply(){
- return this.a * this.b;
- }
-}
-
-class Division extends Calculation { // บรรทัด a -- Division สืบทอดมาจาก Calculation
- constructor (a, b){
- super(a, b); // บรรทัด b -- เรียกใช้คอนสตรัคเตอร์ของ Calculation
-
- // สามารถกำหนดค่าให้กับ this.a และ this.b ที่อยู่ในคลาสแม่ได้โดยตรง
- // แต่การทำเช่นนี้จะไม่ปลอดภัย
- // this.a = a; // ไม่ควรทำ
- // this.b = b; // ไม่ควรทำ
- }
-
- divide(){
- return this.a / this.b;
- }
-}
+C:\ES6>
+ |-- test.js
```
-ในตัวอย่างดังกล่าว คลาส Division จะสืบทอดสมาชิก (พร็อพเพอร์ตี้) จากคลาส Calculation ได้แก่ a, b และ multiply โดยเราสามารถเข้าถึงพร็อพเพอร์ตี้เหล่านี้ได้ (ในตัวอย่างถัดไป)
-
-*** ทั้งนี้ในจาวาสคริปต์จะมีเงื่อนไขว่า คลาสลูกต้องเรียก super() ด้วยเสมอ มิฉะนั้นจะเกิด error
-
-```js
-let div = new Division(20,10);
-
-console.log(div.multiply()); // 200
-console.log(div.divide()); // 2
-console.log(div.a, div.b); // 20 10 (ไม่ควรเข้าถึงข้อมูลอ็อบเจ็กต์โดยตรง ด้วยวิธีนี้)
+รันไฟล์ test.js ผ่านทาง Node.js ด้วยความสั่งต่อไปนี้ ตามรูป
-console.log(div instanceof Division); // true
-console.log(div instanceof Calculation); // true
-console.log(div instanceof Object); // true
-```
-ให้สังเกต ตอนสร้างอ็อบเจ็กต์ด้วยประโยค new Division(20,10); นอกจากเรียกคอนสตรัคเตอร์ของตัวเองแล้ว มันยังเรียกของคลาสแม่ด้วยประโยค super(a, b); (ในบรรทัด b ของคลาส Division) ซึ่งจะหมายความว่าให้ส่ง 20 กับ 10 ไปให้คอนสตรัคเตอร์ของ Calculation เพื่อกำหนดค่าให้กับ this.a และ this.b ตามลำดับ
+
-#### Method overriding
-คลาสลูกที่สืบทอดมาจากคลาสแม่ เมธอดของลูกสามารถโอเวอร์ไรด์ (Override) เมธอดของแม่ได้ด้วย และถ้าเมธอดของคลาสลูกจะเรียกเมธอดของคลาสแม่ (ที่ชื่อซ้ำกัน) ก็ให้เรียกผ่าน super แทน ตัวอย่าง
+## ทวน ES5 (มาตรฐานเก่า)
+## แนะนำ ES6
-```js
-class Calculation {
- constructor (a, b){
- this.a = a;
- this.b = b;
- }
- multiply(){
- return this.a * this.b;
- }
-}
-
-class Multiplying extends Calculation {
- constructor (a, b){
- super(a, b);
- }
- multiply(){ // โอเวอร์ไรด์เมธอด multiply() ของคลาสแม่
- return "The result is " + super.multiply();
- }
-}
-
-let m = new Multiplying(20,10);
-console.log(m.multiply()); // "The result is 200"
-```
+เนื้อหาบทที่ 2 และ 3 ขอลบนะครับ ไม่สามารถนำเนื้อหาออกมาได้เพราะติดลิขสิทธิ์ แต่ตัวอย่างโค้ดสามารถแยกออกให้ดูได้ทีนี้ครับ
-(บทนี้ ยังไม่เสร็จดีครับ)
+[ตัวอย่างโค้ด](https://github.com/adminho/javascript/tree/master/examples_book)
-### 3.7 Collection
-### 3.8 Iterator กับ Generator
-### 3.9 Meta Programming
-### 3.10 Module
-### 3.11 อื่นๆ
+[อ่านเพิ่มได้ในหนังสือ]( https://www.se-ed.com/product/พัฒนาเว็บแอปพลิเคชั่นด้วย-JavaScript.aspx?no=9786160825394)
-## บทที่ 4 แนะนำ ES7
+## แนะนำ ES7
หัวข้อต่อไปนี้จะแสดงฟีเจอร์ใหม่ที่เพิ่มเข้ามาใน ES7 (ECMAScript 2016) รวมทั้งที่เปลี่ยนแปลงไปจาก ES6 ซึ่งมันเปลี่ยนเล็กนิดเดียวเอง
@@ -1098,13 +828,6 @@ console.log(uint8.includes(5)); // true
console.log(uint8.includes(10)); // false
```
-```js
-หมายเหตุ โอเปอเรเตอร์ ** ตามสเปค ES7 ผมยังหาจาวาสคริปต์เอ็นจิ้นรองรับการรันเทสไม่ได้เลย (เศร้าจัง)
-สรุปซอร์สโค้ดที่เห็นในตัวอย่างที่ผ่านมา ขาดการทดสอบจริงจัง
-ดังนั้นถ้าในอนาคตสามารถทดสอบได้ เดี่ยวมาปรับแก้เนื้อหาใหม่
-ตอนนี้เอาคอนเซปท์ให้เห็นไปก่อนแล้วกันเนอะ!
-```
-
### สิ่งที่เปลี่ยนแปลงไปของ ES7 เมื่อเทียบกับ ES6 (นิดเดียวเอง)
หัวข้อก่อนหน้านี้ได้กล่าวถึงฟีเจอร์ที่เพิ่มมาใหม่ใน ES7 แต่หัวข้อนี้จะกล่าวถึงฟีเจอร์ที่เปลี่ยนไปจาก ES6 ดังนี้
@@ -1117,19 +840,82 @@ function * generator() {}
let iterator = new generator(); // throws "TypeError: f is not a constructor"
```
-## บทที่ 5 แนะนำ ES8
+## แนะนำ ES8
+
+สิ่งที่คาดว่าจะเพิ่มเข้ามาใน ES8 (ECMAScript 2017)
+
+* Object.entries() กับ Object.values()
+* padStart() กับ padEnd()
+* Object.getOwnPropertyDescriptors()
+* การใช้คอมม่า (,) ต่อท้ายในพารามิเตอร์ของฟังก์ชั่น ,ตอนเรียกใช้งานฟังก์ชั่น, ในอ็อบเจ็กต์ และอาเรย์
+* Async กับ await
+
+รายละเอียดหาอ่านเพิ่มได้ ในหนังสือแจกฟรีเล่มนี้นะครับ
-สิ่งที่คาดว่าจะเพิ่มเข้ามาใน ES8 (ECMAScript 2017) (มีนิดเดียว)
+http://www.ebooks.in.th/ebook/40184/รีวีวฟรีเจอร์ใหม่ในจาวาสคริปต์_(JavaScript)_มาตรฐาน_ES7__ES8__(ECMAScript_2016_กับ_ECMAScript_2017)/
-* Object.values()
-* Object.entries()
+
+
+## แนะนำ ES9 และ ES10
+
+(รอก่อน)
## อ้างอิง
* [1] หนังสือ “พัฒนาเว็บแอปพลิเคชั่นด้วย JavaScript” จะอธิบายถึงมาตรฐานตัวใหม่ ECMAScript 2015 หรือเรียกสั้น ๆ ว่า “ES6” หรือ “ES6 Harmony” โดยเล่มนี้ตีพิมพ์และจัดจำหน่ายโดยซีเอ็ด
* [2] https://developer.mozilla.org/en-US/docs/Web/JavaScript/
* [3] https://github.com/nzakas/understandinges6/blob/master/manuscript/B-ECMAScript-7.md
-* [4] https://tc39.github.io/ecma262/2016/
+* [4] http://www.ecma-international.org/ecma-262/7.0/
+* [5] https://tc39.github.io/ecma262/
+* [6] https://github.com/google/traceur-compiler/wiki/Getting-Started
+* [7] https://github.com/babel/babel-standalone
+* [8] http://exploringjs.com/es6.html
+* [9] https://leanpub.com/exploring-es2016-es2017/read
+* [10] https://leanpub.com/setting-up-es6/read#sec_es6-repls
+* [11] https://leanpub.com/ecmascript2015es6guide/read
+* [12] https://leanpub.com/understandinges6/read
+* [13] https://github.com/nzakas/understandinges6/tree/master/manuscript
+* [14] https://github.com/sirisian/ecmascript-types
+* [15] http://exploringjs.com/es2016-es2017/
+
+## ทิ้งท้าย
+
+เหตุผลที่เขียนบทความชุดนี้ เพราะหลังจากเขียนหนังสือ ดังกล่าวไปแล้ว (ตามรูปข้างล่าง) เทคโนโลยีจาวาสคริปต์ก็ดูเหมือนพัฒนาต่อเนื่อง (ยังไม่นิ่ง)
+ด้วยเหตุนี้ ....
+* เนื้อหาทั้งหมดต่อไปนี้ จะเหมือนเป็น**ภาคต่อ**จากหนังสือดังกล่าว
+* จะพูดถึงภาษาจาวาสคริปต์ (JavaScript) ยุคสมัยใหม่ตามมาตรฐาน ES7, ES8 (ไม่มีในหนังสือ)
+* รวมทั้งเพิ่มเนื้อหาที่ไม่อยู่ในหนังสือ (คือตอนแต่งหนังสือ เทคโนโลยีต่างๆ ยังไม่อื้ออำนวย ผมเลยไม่กล้าเขียนลงไปครับ)
+* **ทั้งนี้เนื้อหาจะต่างจากหนังสือข้างต้น ไม่เหมือนกันเท่าไร**
+* **เขียนยังไม่เสร็จดี** กะว่าจะทยอยเขียนไปเรื่อยๆ (ถ้ามีเวลาว่าง) ซึ่งถ้าได้ปริมาณมากพอ อนาคตอาจมีรวบรวมทำเป็นเล่ม 2 เพื่อวางขายต่อไป
-
+*** ใครเอาเนื้อหาผมไปใช้ โปรดให้เครดิตลิงค์ต้นฉบับต้นด้วยนะคร๊าบบบบบ
+
+ถ้าสนใจข่าวสารไอที ทั้งสาระบ้าง และไร้สาระบ้าง ก็ตามได้ที่
+
+* https://www.facebook.com/programmerthai/
+
+สามารถให้คำชี้แนะ คอมเมนต์ และฟีดแบ็คผมได้ตลอดเวลา ที่
+
+* http://www.patanasongsivilai.com/javascript.html
+
+
+## สำหรับผู้ที่สนใจหนังสือเล่มนี้
+
+หนังสือ __ภาษาไทยเล่มแรก__ ที่กล่าวถึงจาวาสคริปต์มาตรฐานใหม่ ES6 **ตอนนี้ไม่ตีพิมพ์ซ้ำอีกแล้ว** ยังมีขายบางแห่งเท่านั้น ควรเช็คอีกที
+
+
+
+* [ศูนย์หนังสือจุฬา]( http://www.chulabook.com/description.asp?barcode=9786160825394)
+* [ร้านนายอินทร์](https://www.naiin.com/product/detail/191081/)
+* [ร้าน Book Smile](http://www.booksmile.co.th/คอมพิวเตอร์อินเทอร์เน็ต/พัฒนาเว็บแอบพลิเคชั่นด้วย-JavaScript.html)
+* [ร้าน kinokuniya thailand](https://thailand.kinokuniya.com/bw/9786160825394)
+* [ผ่านฟ้าบุ๊คเซ็นเตอร์] (http://www.phanpha.com/item/พัฒนาเว็บแอปพลิเคชั่นด้วย-javascript)
+* [ซีเอ็ดบางสาขา]( https://www.se-ed.com/product/พัฒนาเว็บแอปพลิเคชั่นด้วย-JavaScript.aspx?no=9786160825394)
+* และร้านหนังสืออื่น ๆ ที่ไม่ได้กล่าว
+
+เล่มใหม่เนื้อหาอัปเดต เป็นจาวาสคริปต์ตั้งแต่ ES6 เป็นต้นไป (ล่าสุดเนื้อหาถึง ES14) เนื้อหาเกือบ 700 กว่าหน้า
+
+
+
+[สั่งซ์้อได้ที่เว็บ MEB (ขายเป็นอีบุ๊กเท่านั้น)](https://www.mebmarket.com/web/index.php?action=BookDetails&data=YToyOntzOjc6InVzZXJfaWQiO3M6NzoiMTcyNTQ4MyI7czo3OiJib29rX2lkIjtzOjY6IjE1Njg1NCI7fQ)
diff --git a/examples/budget_thailand/fiscal_year_2024.html b/examples/budget_thailand/fiscal_year_2024.html
new file mode 100644
index 0000000..aab1c38
--- /dev/null
+++ b/examples/budget_thailand/fiscal_year_2024.html
@@ -0,0 +1,162 @@
+
+
+
+
+ The Budget of Thailand 2024
+
+
+
+
+
+
+ ผ่างบประมาณของประเทศไทยปี 2567
+
+
+
กำลังโหลดข้อมูล รอสักครู่
+
+
+
+
+
+ โปรดติดตามแฟนเพจ https://www.facebook.com/programmerthai
+
+
+
\ No newline at end of file
diff --git a/examples/calendar/README.md b/examples/calendar/README.md
new file mode 100644
index 0000000..ce03bbd
--- /dev/null
+++ b/examples/calendar/README.md
@@ -0,0 +1,5 @@
+# Calendar in hex, decimal and binary
+
+__I borrowed some code from__
+
+* http://www.w3schools.com/howto/howto_css_calendar.asp
diff --git a/examples/calendar/css/calendar.css b/examples/calendar/css/calendar.css
new file mode 100644
index 0000000..3b69462
--- /dev/null
+++ b/examples/calendar/css/calendar.css
@@ -0,0 +1,82 @@
+/*
+
+
+
+
เป็นตัวอย่างเว็บอย่างง่ายๆ เพื่อแสดงวิธีใช้งาน JavaScript ตามมาตรฐานใหม่ ES6 (ใช้ Babel)
+
*** โค้ดนี้ผ่านการลองทดทดสอบบน Firefox, Google เท่านั้นนะครับ
+
+
+
+
+
+ เดือน
+
+ ปี ค.ศ.
+
+ ระบบตัวเลข
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
โค้ดตัวอย่างนี้ จะมีปัญหาเวลาเปิดด้วย Google Chrome
+
ถ้าเห็นว่าไม่ทำงาน ก็รบกวนดูลิงค์ข้างล่างนี้นะครับ มีวิธีแก้ เวลาเปิดด้วย Google Chrome
+
(หัวข้อ Cross-origin resource sharing)
+
+
+
+