สรุปสั้น
- ใช้
constเป็นค่าเริ่มต้น ใช้letเมื่อต้องเปลี่ยนค่า เลิกใช้var- เปรียบเทียบด้วย
===เสมอ- object/array ถูกส่งต่อแบบ อ้างอิง (reference) แก้ตัวหนึ่ง อีกตัวเปลี่ยนตาม
- งานที่ต้องรอ (เรียก API, อ่านไฟล์) ใช้
async/awaitและครอบด้วยtry/catch- ถ้าต้องดึงข้อมูลจากฐานข้อมูลฝั่ง backend ดูต่อที่ พื้นฐาน PHP และ พื้นฐาน SQL
1. ตัวแปร: const, let, var
const name = "Somchai" // เปลี่ยนค่าไม่ได้ (แต่ของข้างใน object ยังแก้ได้)
let count = 0 // เปลี่ยนค่าได้
count++
const user = { age: 20 }
user.age = 21 // ได้ เพราะไม่ได้เปลี่ยนตัวแปร user แค่แก้ของข้างใน| ขอบเขต (scope) | ประกาศซ้ำ | ใช้ก่อนประกาศ | |
|---|---|---|---|
var | ทั้งฟังก์ชัน | ได้ | ได้ค่า undefined (hoisting) |
let / const | ภายใน { } | ไม่ได้ | error (Temporal Dead Zone) |
อย่าใช้
varในโค้ดใหม่
varมองข้ามขอบเขตของ{ }ทำให้เกิดบั๊กแปลก ๆ โดยเฉพาะใน loop
2. ชนิดข้อมูลและการเปรียบเทียบ
ชนิดพื้นฐาน (primitive): string, number, bigint, boolean, undefined, null, symbol
นอกนั้นเป็น object ทั้งหมด (รวม array และ function)
typeof "hi" // "string"
typeof 42 // "number"
typeof null // "object" ← บั๊กเก่าของภาษา จำไว้
typeof [] // "object" → เช็ก array ด้วย Array.isArray([])== กับ ===
0 == "" // true ← แปลงชนิดให้ก่อนเทียบ งง
0 === "" // false ← เทียบทั้งค่าและชนิด
null == undefined // true
null === undefined // falseใช้ === และ !== เสมอ
ค่าที่ถือว่า “เท็จ” (falsy)
false, 0, "", null, undefined, NaN นอกนั้นถือว่า “จริง” ทั้งหมด รวมถึง [] และ {}
?. และ ??
const city = user?.address?.city // ไม่ error ถ้า address ไม่มี ได้ undefined
const limit = input ?? 10 // ใช้ 10 เฉพาะเมื่อ input เป็น null/undefined
const limit2 = input || 10 // ใช้ 10 เมื่อ input เป็น falsy ทุกแบบ (รวม 0!)3. ฟังก์ชัน
function add(a, b) { return a + b } // function declaration
const add2 = (a, b) => a + b // arrow function
const greet = (name = "เพื่อน") => `สวัสดี ${name}` // ค่าเริ่มต้น + template string
thisใน arrow functionarrow function ไม่มี
thisของตัวเอง มันใช้thisของที่ที่มันถูกเขียนไว้ เหมาะกับ callback แต่ไม่เหมาะเป็น method ของ object
Closure: ฟังก์ชันจำตัวแปรรอบตัวได้
function makeCounter() {
let count = 0
return () => ++count
}
const next = makeCounter()
next() // 1
next() // 2 ← count ยังอยู่ แม้ makeCounter จบไปแล้ว4. Object และ Array
Destructuring และ Spread
const { name, age = 18 } = user // ดึง property ออกมาเป็นตัวแปร
const [first, ...rest] = [1, 2, 3] // first = 1, rest = [2, 3]
const updated = { ...user, age: 30 } // copy แล้วแก้บาง field
const merged = [...arr1, ...arr2]Method ของ array ที่ใช้บ่อยที่สุด
const prices = [100, 250, 80]
prices.map(p => p * 1.07) // แปลงทุกตัว → array ใหม่
prices.filter(p => p > 90) // กรอง → array ใหม่
prices.reduce((sum, p) => sum + p, 0) // รวมเป็นค่าเดียว → 430
prices.find(p => p > 90) // ตัวแรกที่ตรง → 100
prices.some(p => p > 200) // มีสักตัวไหม → true
prices.includes(80) // มีค่านี้ไหม → truemap, filter ไม่แก้ array เดิม แต่ sort, push, splice แก้ของเดิม ถ้าไม่อยากให้เดิมเปลี่ยน ใช้ toSorted() แทน sort()
Reference: กับดักอันดับหนึ่ง
const a = { score: 1 }
const b = a // b ชี้ไปที่ object เดียวกัน ไม่ได้ copy
b.score = 99
a.score // 99 !
const shallow = { ...a } // copy แค่ชั้นแรก
const deep = structuredClone(a) // copy ทุกชั้น5. Asynchronous: Promise และ async/await
JavaScript ทำงานทีละคำสั่ง (single thread) งานที่ต้องรอ เช่น เรียก API จะถูกฝากไว้ แล้วกลับมาทำต่อเมื่อเสร็จ ผ่านกลไกที่เรียกว่า event loop
async function loadUser(id) {
try {
const res = await fetch(`/api/users/${id}`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return await res.json()
} catch (err) {
console.error("โหลดผู้ใช้ไม่สำเร็จ", err)
return null
}
}ทำหลายงานพร้อมกัน แทนที่จะรอทีละอัน:
const [user, orders] = await Promise.all([loadUser(1), loadOrders(1)])
fetchไม่ throw เมื่อได้ 404 หรือ 500ต้องเช็ก
res.okเอง ไม่อย่างนั้นจะได้ข้อมูล error ไปใช้ต่อแบบไม่รู้ตัว
6. Module: import / export
// math.js
export const add = (a, b) => a + b
export default function multiply(a, b) { return a * b }
// app.js
import multiply, { add } from "./math.js"7. DOM และ Event (ฝั่งเบราว์เซอร์)
const button = document.querySelector("#save")
button.addEventListener("click", (event) => {
event.preventDefault()
document.querySelector("#status").textContent = "บันทึกแล้ว"
})ใช้ textContent เมื่อแสดงข้อความจากผู้ใช้ อย่าใช้ innerHTML กับข้อมูลที่ผู้ใช้กรอก เพราะเปิดช่องให้ฝังสคริปต์ (XSS)
จุดที่มักพลาด
0.1 + 0.2 === 0.3เป็นfalseเพราะทศนิยมแบบ floating point → เรื่องเงินให้เก็บเป็นหน่วยสตางค์ (จำนวนเต็ม)NaN === NaNเป็นfalse→ เช็กด้วยNumber.isNaN(x)- ลืม
awaitได้ Promise แทนข้อมูลจริง parseInt("08")ได้ 8 แต่parseInt("1,000")ได้ 1 → ลบ,ก่อนแปลง[10, 9, 1].sort()ได้[1, 10, 9]เพราะเรียงแบบข้อความ → ใช้.sort((a, b) => a - b)
แหล่งอ้างอิง
- MDN Web Docs: JavaScript Guide · https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide
- javascript.info: The Modern JavaScript Tutorial · https://javascript.info/