JavaScript พื้นฐาน (ES6)

JavaScript ไม่ใช่ Java — คนละภาษากัน สร้างปี 1994 โดย Brendan Eich ที่ Netscape เดิมชื่อ Mocha → LiveScript → JavaScript และปี 1997 ECMA International ทำให้เป็นมาตรฐานชื่อ ECMAScript

JavaScript ทำอะไรได้บ้าง

ฝั่งทำอะไร
Client-sideจัดการ DOM — เพิ่ม ลบ แทรก element
จัดการการโต้ตอบกับผู้ใช้
ส่งข้อมูลผ่าน HTTP แบบ synchronous แล้ว reload หน้า
ส่งข้อมูลผ่าน AJAX — ไม่ต้องรอ response และเปลี่ยนเฉพาะบางส่วนของหน้า
Server-sideเขียน backend ด้วย NodeJS

วิธีใส่ JS ในหน้าเว็บ

<!-- 1. เขียนในไฟล์ HTML เลย -->
<script type="text/javascript">
    // code
</script>

<!-- 2. เรียกจากไฟล์อื่น -->
<script src="script.js"></script>

<!-- protocol-relative path -->
<script src="//example.com/script.js"></script>

alert / confirm / document.write / console.log

alert("ข้อความ");                 // แจ้งเตือนผู้ใช้
let a = confirm("ข้อความ");       // true เมื่อกด OK, false เมื่อกด Cancel
document.write("ข้อความ");        // เขียนลงหน้า HTML
console.log("ข้อความ หรือ ตัวแปร"); // พิมพ์ที่ console — ใช้ debug ไม่แสดงบนหน้าเว็บ

// comment แบบบรรทัดเดียว
/* comment
   หลายบรรทัด */

ตัวแปรและกฎการตั้งชื่อ

ชนิดข้อมูล

ชนิดคำอธิบายตัวอย่าง
numberตัวเลข1, -10, 0.5, 1.2e5
stringข้อความ"hello", 'hello', `hello`
booleanค่าความจริงtrue / false
nullกำหนดว่า "ไม่มีค่า"null
undefinedยังไม่ได้กำหนดค่าundefined
NaNหาค่าไม่ได้10/0 ในบางกรณี
console.log(typeof 42);                 // number
console.log(typeof 'blubber');          // string
console.log(typeof true);               // boolean
console.log(typeof undeclaredVariable); // undefined
null vs undefined vs error
var a;
console.log(a);        // undefined — ประกาศแล้วแต่ยังไม่ให้ค่า

var b = null;
console.log(b);        // null — ตั้งใจบอกว่าไม่มีค่า
console.log(b.a);      // Error! อ่าน property ของ null ไม่ได้

แปลงชนิดข้อมูล

// string → number
console.log(parseInt("10"));        // 10
console.log(parseFloat('   10  ')); // 10 — มีช่องว่างได้

// number → string
let A = 10;
console.log(A + "");                // "10"
console.log(A.toString());          // "10"
// console.log(10.toString());     // Error! เขียนแบบนี้ไม่ได้

var / let / const & Block Scope

เปลี่ยนค่าได้ไหมขอบเขตควรใช้ไหม
varได้ทะลุทุก block scope (เห็นทั้ง if / loop) แต่ไม่ทะลุ function scopeJS รุ่นใหม่ไม่ค่อยใช้แล้ว
letได้เฉพาะใน block ที่ประกาศใช้เมื่อค่าจะเปลี่ยน
constไม่ได้ — เป็นค่าคงที่เฉพาะใน blockใช้เป็นค่าเริ่มต้นเสมอ
var — ทะลุ block var x = 10; if (x === 10) { var y = 100; } console.log(y); → 100 เห็นค่าได้แม้อยู่นอกบล็อก let — ไม่ทะลุ block var x = 10; if (x === 10) { let y = 100; } console.log(y); → error / undefined ตัวแปรอยู่แค่ในบล็อก

ES6 เพิ่ม let และ const เข้ามาแก้ปัญหา scope ของ var

ข้อควรระวังเรื่อง function scope: ถ้าประกาศ var ไว้ใน function ข้างนอก function จะไม่เห็นตัวแปรนั้น — var ทะลุได้เฉพาะ block ที่ไม่ใช่ function เท่านั้น

Hoisting

console.log(x)        // undefined  ← var ถูกยกประกาศขึ้นไปข้างบน
console.log(print())  // print      ← function ก็ถูก hoist
var x = 3
function print() { console.log('print') }

// แต่ถ้าใช้ let หรือ const
console.log(x)        // ReferenceError: x is not defined
let x = 3
Hoisting = ตัวแปร/ฟังก์ชันถูก "ยกประกาศ" ขึ้นไปบนสุดของ scope — var ได้ค่า undefined ส่วน let/const จะ error ถ้าใช้ก่อนประกาศ

Operator

// Arithmetic
+  -  *  /
++  → บวก 1        --  → ลบ 1
**  → ยกกำลัง      %   → หาเศษ (modulo)

// Assignment
x = y        x += y  → x = x + y
x -= y       x *= y       x /= y

ลำดับความสำคัญ: ( … )*** / %+ -

== vs === — ข้อสอบถามแน่

var a = 10;
var b = '10';

a == b    // true  — equality เทียบเฉพาะค่า (แปลงชนิดให้ก่อน)
a === b   // false — identically เทียบทั้งค่าและชนิด
เครื่องหมายความหมาย
==เท่ากัน (equality) — ไม่สนชนิด
===เหมือนกันทุกประการ (identically) — สนชนิดด้วย
!=ไม่เท่ากัน
!==ไม่เหมือนกันแบบ identically
> < >= <=เปรียบเทียบมากน้อย

Boolean / truthy-falsy

Boolean("hello")   // true
Boolean(5)         // true
Boolean(9.99)      // true

Boolean("")        // false
Boolean(0)         // false
Boolean(-0)        // false
Boolean(null)      // false
Boolean(undefined) // false

เงื่อนไข

if (เงื่อนไข) {
    // ทำเมื่อจริง
} else if (เงื่อนไข2) {
    // ทำเมื่อเงื่อนไข 2 จริง
} else {
    // ทำเมื่อเท็จ
}

switch (month) {
    case 1: console.log("มกราคม"); break;
    case 2: console.log("กุมภาพันธ์"); break;
    default: console.log("ไม่พบเดือน");
}
ลืม break ใน switch จะทำให้ไหลลงไปทำ case ถัดไปด้วย (fall-through)

Loop 4 แบบ

while (เงื่อนไข) { }                       // เช็คก่อนทำ

do { } while (เงื่อนไข);                   // ทำ 1 รอบก่อนแล้วค่อยเช็ค

for (let i = 1; i <= 100; i++) { }         // ค่าเริ่มต้น; เงื่อนไข; เปลี่ยนค่า
คำสั่งผลลัพธ์
breakออกจาก loop ที่อยู่ข้างในสุดทันที
continueหยุดรอบปัจจุบัน แล้วย้อนไปเริ่มรอบใหม่

for / forEach / for-in / for-of

let myArray = [1, 2, 3];

// for ปกติ — ใช้ index
for (let i = 0; i < myArray.length; i++) { console.log(myArray[i]); }

// forEach — วนสมาชิกของ array
myArray.forEach(element => { console.log(element); });

// for-in — วน key ของ object
let dog = { name: "Yoyo", color: "black", age: 2 };
for (const key in dog) {
    console.log(key + " : " + dog[key]);
}

// for-of — วนค่าของสิ่งที่มี index เช่น array, set, string
for (const iterator of "hello") { console.log(iterator); }  // h e l l o
จำง่าย: for-in ได้ key · for-of ได้ value
use strict: ถ้าไม่ประกาศ var/let/const นำหน้า ตัวแปรจะกลายเป็น global โดยอัตโนมัติ ใส่ "use strict"; เพื่อบังคับให้ต้องประกาศตัวแปรเสมอ

function & arrow function

// JS รุ่นเก่า
function f1(param1) {
    return "p1: " + param1;
}

// Arrow function — กระชับกว่า
let f1 = (param1) => "p1: " + param1;

// ถ้าโค้ดยาว ใส่ปีกกาและ return
let hello = () => {
    return "Hello World!";
};
// default parameter
function myFunction(x, y = 2) { }

String & template literal

'สวัสดี' + 'ชาวโลก'                // ต่อสตริงด้วย +

let text = `The quick brown fox
jumps over the lazy dog`;         // back tick = ขึ้นบรรทัดใหม่ได้

let dog = "dog";
let text2 = `jumps over the lazy ${dog}`;  // interpolation — ใช้ได้เฉพาะ back tick

Spread & Rest

// Spread (...) — กระจายสมาชิกของ array
const numbersOne = [1, 2, 3];
const numbersTwo = [4, 5, numbersOne];
console.log(numbersTwo);     // [4, 5, [1,2,3]]  ← ซ้อนเป็น array ใน array

const numbersThree = [4, 5, ...numbersOne];
console.log(numbersThree);   // [4, 5, 1, 2, 3]  ← กระจายออกมา

// Rest (...) — รับ parameter ไม่จำกัดจำนวน
function fun(...input) {
    let sum = 0;
    for (let i of input) { sum += i; }
    return sum;
}
console.log(fun(1, 2));          // 3
console.log(fun(1, 2, 3, 4, 5)); // 15
เครื่องหมายเหมือนกันแต่คนละหน้าที่: อยู่ตอนเรียกใช้ = spread (กระจายออก) · อยู่ในพารามิเตอร์ของฟังก์ชัน = rest (รวบเข้ามา)

JSON

{
    "key1": "value1",
    "key2": [ value, object ]
}
JS ObjectJSON Object
เก็บ function ได้ไหมได้ไม่ได้
key ต้องมีเครื่องหมายคำพูดไหมไม่ต้องต้องมี (double quote)
ใช้ทำอะไรโครงสร้างข้อมูลในโปรแกรมมาตรฐานการสื่อสาร API
JSON.stringify({"a":"1"});                       // object → string
const s = '{"result":true, "count":42}';
JSON.parse(s);                                   // string → object

เข้าถึงข้อมูลใน object ได้ 2 แบบ:

let user = { name: 'A' };
user.name        // A
user["name"]     // A

Timer & Math

setTimeout(sayHello, 3000);         // เรียก 1 ครั้งหลังผ่านไป 3 วินาที
setInterval(sayHello, 2000);        // เรียกซ้ำทุก 2 วินาที

let id = setTimeout(sayHello, 3000);
clearTimeout(id);                   // ยกเลิกก่อนถึงเวลา

let iid = setInterval(sayHello, 2000);
setTimeout(() => clearInterval(iid), 10000);   // หยุดหลัง 10 วินาที

Math.random();                      // ทศนิยม 0 <= x < 1
Math.floor(Math.random() * 10);     // จำนวนเต็ม 0-9
Math.floor(Math.random() * 11);     // จำนวนเต็ม 0-10