หลังจาก Blog ตอนก่อน ก้าวเข้าสู่โลกของ Frontend เริ่มเล่น Nodejs ลงเพื่อให้ได้ตัว NPM มานะครับ คราวนี้ผมลองศึกษาตัว ECMAScript 6 โดยดูจาก GitHub ECMAScript 6 Tutorial ใส่ตัวอย่างจาก Git เข้ายก Mortgage Calculator ที่มี amortization และเราลองทำตามขั้นตอนที่ผู้เขียนแนะนำครับ
ECMAScript 6 คือ JavaScript แหละ ที่ปรับเปลี่ยนให้ตามยุคสมัยมากขึ้น
- Use Strict
อันนี้มีมาตั้งแต่ ECMAScript 5 แล้ว แต่ถ้าใครมาจากภาษาที่แบบเคร่งอยากให้เปิดไว้ เช่น
- มันจะได้เตือน Error มา และเขียน Code ได้ดีขึ้นด้วย
// Non-strict mode function divide(x, y) { return x / y; } console.log(divide(10, 0)); // Output: Infinity (no error thrown)
// Strict mode "use strict"; function divideStrict(x, y) { return x / y; } console.log(divideStrict(10, 0)); // Output: Infinity (TypeError: Division by zero)
- Optimization Enhancements มันไม่จำเป็นต้องมาตรวจ Type ตอน Runtime
'use strict'; //unnecessary runtime checks / behaviors related ถูกตัดออกไป function sum(a, b) { return a + b; } sum(10, 20);
- Undeclared Variables - เมื่อก่อน javascript มันประกาศตัวแปรลอยได้เลยไง อันนี้แหละ ผมไม่ชอบ ตัว
'use strict'
มาช่วยบังคับตรงนี้ จะได้ throw a ReferenceError ออกมา
จริงๆ เรื่องนี้มีอีกหลายอันเลย เรื่อง use strict แต่เอาเท่านี้ก่อน
JavaScript ใช้ reference pointer - เราไปยุ่งตรงๆไม่ได้ แต่มันอยู่เบื้องหลังให้เราใช้งาน https://stackoverflow.com/a/17382443/20000255
- การประกาศตัวแปร
ของเดิม var แล้วจะทำอะไรก็ได้ แต่ปัญหาของมัน คือ ตัวแปรประเภท var มี Scope เป็น Global ครับ
- Code ตัวอย่าง
var num = 10 console.log('before num = '+ num) if (num == 10){ var num = 26 console.log('inside if block num = '+ num) } console.log('after num = '+ num)
- ผลลัพธ์
before num = 10 inside if block num = 26 //ใน IF มีการแก้ค่า ถ้าเว็บใหญ่นี้หากันตายเลย after num = 26
ของใหม่เพิ่ม let / const เข้ามา
let เหมือน var แต่มี Scope อยู่ใน Block ของการทำงานครับ จะเป็นโมดูล หรือ Function
- Code ตัวอย่าง
let num = 10 console.log('before num = '+ num) if (num == 10){ let num = 26 console.log('inside if block num = '+ num) } console.log('after num = '+ num)
- ผลลัพธ์
before num = 10 inside if block num = 26 //ตัวแปร ใน IF กับนอก IF เป็นคนะตัว after num = 10
อีกตัวเป็น const เก็บค่างคงที ห้ามแก้ไขหลังประกาศ
- Code ตัวอย่าง
const num = 10 console.log('before num = '+ num) if (num == 10){ num = 26 console.log('inside if block num = '+ num) } console.log('after num = '+ num)
- ผลลัพธ์ - ระบบมันด่าเราครับ ดังนี้
- Data Type
ใหม่ Destructoring - ดึงข้อมูลบางส่วนมาจาก Array
ใหม่ template string แทนที่เราต้องเอาตัวแปร + เชื่อม String ต่อกัน ยิ่งข้อความยาวๆ ผิดที่งงเลย เรามาทำเป็น Template แล้วใช้งานมันแทน
- Code ตัวอย่าง
const message = [ 'Chatri', 'Ngambenchawong', 'Ping' ] const [first,,third] = message console.log(- Old way) console.log('Hi, My name is '+ first + ' ('+third+')' ) console.log(- Template String) console.log(`Hi, My name is ${first} (${third})`)
- สำหรับ Template String ข้อความ Template ต้องอยู่ในตัว ` (Grave ที่ใช้เปลี่ยนภาษาครับ) อ้างถึงตัวแปรโดยใช้ ${ชื่อตัวแปร} ครับ โดยผลลัพธ์ที่ได้ตามนี้ครับ
- Old way Hi, My name is Chatri (Ping) - Template String Hi, My name is Chatri (Ping)
- function
เดิม วางที่ไหนก็ได้ ผลลัพธ์เท่ากัน
- Code ตัวอย่าง
function add (x, y){ return x + y } console.log('Result from add function is ' + add(5,3)) console.log('Result from minus function is ' + add(5,3)) function minus (x, y){ return x + y }
- ผลลัพธ์
Result from add function is 8 Result from minus function is 8
ใหม่ Arrow Function
Arrow Function บังคับให้ประกาศก่อนใช้งานครับ สังเกตุดีๆมีคำว่า Const
- Code ตัวอย่าง
const addArrowStype = (x,y) => x + y console.log('Result from add(ArrowStype) function is ' + addArrowStype(5,3)) console.log('Result from minus(ArrowStype) function is ' + minusArrowStype(5,3)) const minusArrowStype = (x,y) => x + y
- ผลลัพธ์ ถ้าลองมาดูผลลัพธ์ที่ได้ อันแรกไม่มีปัญหา แต่ Function ที่ minusArrowStype ดันมาเรียกใช้ก่ออนประกาศ โดนโปรแกรมด่าครับ
ถ้า Arrow Function มีหลายบรรทัดหละ ใส่ { } ได้
- Code ตัวอย่าง
const mulArrowStype = (x,y) => { let z = x * y return z } console.log('Result from add(ArrowStype) function is ' + mulArrowStype(5,3))
- ถ้าลองมาดูผลลัพธ์ที่ได้
Result from add(ArrowStype) function is 15
- Structure กับ this
มาลอง Function แบบเดิมๆกัน
- Code ตัวอย่าง
const obj = { x: 26, y: 28, sum: function () { return this.x + this.y } } console.log(obj.sum())
- Note: Code ข้างบนนี้ทำงานได้ครับ โดยได้ผลลัพธ์เท่ากับ 54 แต่ถ้ามาลองกับ Arrow Function หละ
const obj1 = { x: 26, y: 28, sum: () => { return this.x + this.y } } console.log(obj1.sum())
- ผลลัพธ์ที่ได้ คือ NaN เพราะ ตอนนี้ Arrow Function ยังไม่รู้จักกับ this ครับ
- ระวัง side effect ของ Function
ระวัง side effect - ค่าตัวแปรที่อยู่นอก เมื่อเข้าไปใน Function แล้วถูกแก้ไขค่า ถ้าเป็นฝั่ง Java, C# โยน Object เข้าไป แต่มันส่ง Reference เข้าไป เวลาแก้ไขต้องระวังด้วย
- Code ตัวอย่าง
let x = 0 console.log('Intial') console.log(x) function addSideEffect(a){ console.log('In Function') x = x + a console.log(x) } addSideEffect(15) console.log('After Call FN addSideEffect') console.log(x)
- ผลลัพธ์ที่ได้
Intial 0 In Function 15 After Call FN addSideEffect 15
แล้วเราจะป้องกันอย่างไร ต้องดูก่อนครับ ว่า Function นั้นจำเป็นต้องแก้ค่าของตัวแปรที่ส่งเข้าไปไหม ถ้าไม่ก็สร้างตัวแปรใหม่แยกไปเลย ดังนี้
- Code ตัวอย่าง
console.log('Prevent FN addSideEffect') const y = 0 console.log('Intial') console.log(y) function preventSideEffect(b){ console.log('In Function') console.log( y + b) return y + b } const newY = preventSideEffect(15) console.log('After Call FN preventSideEffect') console.log(y) console.log('new y return from FN preventSideEffect') console.log(newY)
- ผลลัพธ์ที่ได้
Prevent FN addSideEffect Intial 0 In Function 15 After Call FN preventSideEffect 0 new y return from FN preventSideEffect 15
- Class
เดิม ประกาศ function เอา ใช้ไปเยอะมันจะงง ดังนี้
- Code ตัวอย่าง
function Student (firstname, lastname){ this.firstname = firstname this.lastname = lastname this.sayhi = function(){ console.log('Hi, My name is ' + this.firstname + ' ' + this.lastname) } } //หรือใช้ Prototype Student.prototype.sayMajor = function(major){ console.log(this.firstname + ' is study in major Computer Science-'+major) } var adminping = new Student('Chatri', 'Ngambenchawong') adminping.sayhi() adminping.sayMajor('Software Engineering')
- ผลลัพธ์ที่ได้
Hi, My name is Chatri Ngambenchawong Chatri is study in major Computer Science-Software Engineering
ใหม่มี Class ให้เล่นเลย ลองแปลง Code ก่อนหน้ามาเป็น class ครับ
- Code ตัวอย่าง
class Student { constructor(firstname, lastname) { this.firstname = firstname this.lastname = lastname } //Method sayhi (){ console.log('Hi, My name is ' + this.firstname + ' ' + this.lastname) } sayMajor (major){ console.log(this.firstname + ' is study in major Computer Science-'+major) } } var adminping = new Student('Chatri', 'Ngambenchawong') adminping.sayhi() adminping.sayMajor('Software Engineering')
- ผลลัพธ์ที่ได้
Hi, My name is Chatri Ngambenchawong Chatri is study in major Computer Science-Software Engineering
เมื่อมันเป็น Class มันมีคุณสมบัติของ OO มาด้วย เช่น Extend ลองดูตัวอย่างครับ โดยผมมาโม Code ก่อนหน้านี้เป็น ดังนี้
- Code ตัวอย่าง
class Student { constructor(firstname, lastname) { this.firstname = firstname this.lastname = lastname } //Method sayhi (){ console.log('Hi, My name is ' + this.firstname + ' ' + this.lastname) } sayMajor (major){ console.log(this.firstname + ' is study in major Computer Science-'+major) } } class bachelorStudent extends Student { constructor(firstname, lastname, interest) { super(firstname, lastname) this.interest = interest } sayMajor (major){ console.log(this.firstname + ' is study in major Computer Science-'+major) } sayInterest(){ console.log('My Interest is ' + this.interest) } } var adminping = new Student('Chatri', 'Ngambenchawong') adminping.sayhi() adminping.sayMajor('Software Engineering') var pingkunga = new bachelorStudent('Pingkung', 'Debugging', 'Technology, food mania') pingkunga.sayhi() pingkunga.sayMajor('Data Science') pingkunga.sayInterest()
- ผลลัพธ์ที่ได้
Hi, My name is Chatri Ngambenchawong Chatri is study in major Computer Science-Software Engineering Hi, My name is Pingkung Debugging Pingkung is study in major Computer Science-Data Science My Interest is Technology, food mania
- Object
เดิม Object สามารถสร้าง และเพิ่ม Property ระหว่างทำงานได้ ด้วย
- Code ตัวอย่าง
const Equity = { security_id: 26, security_code: 'IFEC', mtmdate : '2016-09-29', mtmprice : 6.23 } console.log('-------------------------------------------') var sec_id = Equity.security_id var sec_code = Equity.security_code var mtmdate = Equity.mtmdate var mtmprice = Equity.mtmprice console.log(sec_id) console.log(sec_code) console.log(mtmdate) console.log(mtmprice) console.log('-------------------------------------------') console.log('Add new property') Equity.par = 1 console.log(Equity.par)
- ผลลัพธ์ที่ได้
------------------------------------------- 26 IFEC 2016-09-29 6.23 ------------------------------------------- Add new property 1
> Object Destructoring
Object Destructoring ดึงข้อมูลบางส่วนมาจาก Object ดังนี้
- ของเดิม Code ตัวอย่าง
//ของเดิม 3 บรรทัด var sec_id = Equity.security_id var sec_code = Equity.security_code var sec_par = Equity.par
- ของใหม่ - สั้นกระทัดรัด
//ของใหม่สั้นกระทัดรัด const {security_id, security_code, par} = Equity
> Object.assign
ต้องมาดูก่อนว่าทำไม ถึงมี Method นี้ ขั้นแรกเลย ลองสร้าง Object มาก่อน
const Equity = { security_id: 26, security_code: 'IFEC', mtmdate : '2016-09-29', mtmprice : 6.23 } console.log(Equity)
- ลองดูผลลัพธ์
{ security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23 }
- ลองสร้าง Object ใหม่ แล้วเพิ่ม Property ดูครับ
console.log('--------------------------------') console.log('JavaScript is a reference') const newEquity = Equity Equity.regisdate = '1990-04-24' console.log('After add property') console.log('- Old Object') console.log(Equity) console.log('- New Object') console.log(newEquity)
- ลองดูผลลัพธ์ เมื่อเพิ่ม Property ใหม่ มันดันไปแก้ของเก่าด้วย
-------------------------------- JavaScript is a reference After add property - Old Object { security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23, regisdate: '1990-04-24' } - New Object { security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23, regisdate: '1990-04-24' }
- เปลี่ยนมาให้ใช้แบบถึกๆ ยัดตรงๆที่ละตัวเลย
const BruteforceEquity = {} console.log('- Empty Object') console.log(BruteforceEquity) console.log('- Assign Value') BruteforceEquity.security_id = Equity.security_id BruteforceEquity.security_code = Equity.security_code BruteforceEquity.mtmdate = Equity.mtmdate BruteforceEquity.mtmprice = Equity.mtmprice console.log('- Print Object') console.log(Equity) console.log('- Add new property') BruteforceEquity.regisdate = '1990-04-24' console.log('- Old Object') console.log(Equity) console.log('- New Object') console.log(BruteforceEquity)
- ลองดูผลลัพธ์
-------------------------------- Brute force assign - Empty Object {} - Assign Value - Print Object { security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23 } - Add new property - Old Object { security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23 } - New Object { security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23, regisdate: '1990-04-24' }
ลองใช้ Object.assign
- Code ตัวอย่าง
console.log('Use Object.assign') const AssignEquity = Object.assign({}, Equity, { regisdate: '1990-04-24'}) console.log('- Old Object') console.log(Equity) console.log('- New Object') console.log(AssignEquity)
- ผลลัพธ์ ก่อนอื่น Code สั้นลงเยอะครับ แต่มีข้อจำกัด Object.assign ตัว Web Browser ยังไม่รองรับ ต้องใช้ Tools ไปแปลงเป็น ES5 อีกที
-------------------------------- Use Object.assign - Old Object { security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23 } - New Object { security_id: 26, security_code: 'IFEC', mtmdate: '2016-09-29', mtmprice: 6.23, regisdate: '1990-04-24' }
จบไปแล้ว แต่ยังไม่ได้ลองเล่นตัว GitHub ที่แชร์ไว้เลย 5555
lodash.js คือ Library ช่วยให้การเขียน javascript บน browser เข้าใจว่าเป็นพวก Utility
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.