ES6 JavaScript: let, const, arrow function, template literal và các tính năng cần biết
ES6 (ECMAScript 2015) là bản cập nhật lớn nhất trong lịch sử JavaScript. Nếu bạn học JS hôm nay thì ES6 là tiêu chuẩn mặc định — không phải tùy chọn. Gần như mọi code JavaScript hiện đại đều dùng cú pháp ES6.
Bài này tổng hợp các tính năng ES6 quan trọng nhất, kèm so sánh trước/sau để thấy rõ tại sao chúng được tạo ra.
let và const — Thay thế var
var có nhiều hành vi không trực quan gây bug khó tìm. ES6 đưa ra let và const để thay thế:
// var — function scope, bị hoisting, khai báo lại được
var x = 10;
if (true) {
var x = 20; // Ghi đè x bên ngoài!
}
console.log(x); // 20 — không như mong đợi
// let — block scope, phải khai báo trước khi dùng
let y = 10;
if (true) {
let y = 20; // y riêng trong block này
}
console.log(y); // 10 — đúng rồi
// const — block scope, không thể gán lại
const PI = 3.14159;
// PI = 3; // TypeError
// Quy tắc: dùng const mặc định, let khi cần gán lại, không bao giờ var
Arrow Function — Hàm mũi tên
// ES5
function add(a, b) {
return a + b;
}
// ES6 — Ngắn hơn, phổ biến hơn
const add = (a, b) => a + b;
// Nhiều biến thể
const multiply = (x, y) => x * y;
const double = x => x * 2; // 1 tham số: bỏ ngoặc
const greet = () => "Xin chào!"; // Không tham số: giữ ngoặc
// Thân hàm nhiều dòng
const getInfo = (name, age) => {
const message = `${name}, ${age} tuổi`;
return message;
};
// Dùng với map/filter — rất phổ biến
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]
const evens = numbers.filter(n => n % 2 === 0); // [2, 4]
Template Literal — Chuỗi thông minh
const name = "An";
const age = 22;
// ES5 — rườm rà
const msg1 = "Xin chào, tôi là " + name + ", " + age + " tuổi.";
// ES6 — gọn và rõ hơn
const msg2 = `Xin chào, tôi là ${name}, ${age} tuổi.`;
// Chuỗi nhiều dòng
const html = `
<div>
<h1>${name}</h1>
<p>${age} tuổi</p>
</div>
`;
// Biểu thức bên trong ${}
const price = 100000;
console.log(`Giá sau thuế: ${price * 1.1} VND`);
console.log(`${age >= 18 ? "Người lớn" : "Trẻ em"}`);
Destructuring — Gán biến từ array/object
// Array Destructuring
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
// Bỏ qua phần tử
const [first, , third] = [10, 20, 30];
// Rest — lấy phần còn lại
const [head, ...tail] = [1, 2, 3, 4, 5];
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]
// Object Destructuring
const person = { name: "An", age: 22, city: "HN" };
const { name, age } = person;
// Đặt tên biến khác
const { name: fullName } = person; // fullName = "An"
// Giá trị mặc định
const { phone = "Chưa có" } = person; // phone = "Chưa có"
Spread và Rest Operator
// Spread: mở rộng array/object
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const combined = { ...obj1, ...obj2 }; // { a: 1, b: 2 }
// Sao chép (tránh thay đổi original)
const copy = [...arr1];
const objCopy = { ...obj1 };
// Rest: gom tham số còn lại
function sum(...numbers) {
return numbers.reduce((acc, n) => acc + n, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
Default Parameters
// ES5 — cách cũ
function greet(name) {
name = name || "bạn";
return "Xin chào, " + name;
}
// ES6 — rõ ràng hơn
const greet = (name = "bạn") => `Xin chào, ${name}`;
greet(); // "Xin chào, bạn"
greet("An"); // "Xin chào, An"
greet(undefined); // "Xin chào, bạn"
Class — Lập trình hướng đối tượng
class Animal {
constructor(name, sound) {
this.name = name;
this.sound = sound;
}
speak() {
return `${this.name} kêu ${this.sound}`;
}
}
// Kế thừa
class Dog extends Animal {
constructor(name) {
super(name, "gâu gâu");
}
fetch() {
return `${this.name} đang lấy bóng`;
}
}
const dog = new Dog("Buddy");
dog.speak(); // "Buddy kêu gâu gâu"
dog.fetch(); // "Buddy đang lấy bóng"
Module — import và export
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
// main.js
import multiply, { PI, add } from './math.js';
console.log(PI); // 3.14159
console.log(add(2, 3)); // 5
console.log(multiply(4, 5)); // 20
Promise — Xử lý bất đồng bộ
const fetchUser = (id) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) resolve({ id, name: "An", age: 22 });
else reject(new Error("ID không hợp lệ"));
}, 1000);
});
};
fetchUser(1)
.then(user => console.log(user.name)) // "An"
.catch(err => console.error(err.message));
Bảng tổng hợp ES6
| Tính năng | Trước ES6 | ES6 |
|---|---|---|
| Khai báo biến | var | let, const |
| Hàm | function() {} | () => {} |
| Nối chuỗi | "Hi " + name | `Hi ${name}` |
| Gán từ object | const x = obj.x | const { x } = obj |
| Gộp array | arr1.concat(arr2) | [...arr1, ...arr2] |
| OOP | function + prototype | class + extends |
| Module | require() (CommonJS) | import/export |
| Bất đồng bộ | Callback | Promise, async/await |
Kết luận
ES6 không phải "phiên bản nâng cao" — đây là JavaScript hiện tại. Trong số các tính năng trên, let/const, arrow function, template literal, và destructuring là những gì bạn sẽ dùng hàng ngày ngay từ những bài đầu tiên.