[JS Basics] ES6+ Features: Những điều cần biết để viết code JavaScript hiện đại

Chắc hẳn bạn đã nghe nhiều về ES6, nhưng bạn có biết rằng thế giới JavaScript đã tiến xa hơn rất nhiều với những phiên bản tiếp theo, thường được gọi chung là ES6+? Đây không chỉ là những bản cập nhật nhỏ, mà là cả một cuộc cách mạng, trang bị cho lập trình viên những công cụ mạnh mẽ, giúp viết code sạch hơn, hiệu quả hơn và dễ bảo trì hơn.

ES6+ Features: Những điều cần biết để viết code JavaScript hiện đại

Trong bài viết này, hãy cùng bước vào hành trình tìm hiểu những tính năng đột phá của ES6+, đã và đang định hình lại cách chúng ta lập trình JavaScript hiện đại.

ES6 (ECMAScript 2015): Nền móng cho kỷ nguyên mới

ES6 được coi là bản cập nhật lớn nhất và quan trọng nhất trong lịch sử JavaScript. Nó đã đặt nền móng vững chắc cho sự phát triển của ngôn ngữ này.

let và const: Nói lời tạm biệt với var

Trước đây, var là cách duy nhất để khai báo biến, nhưng nó đi kèm với những hành vi khó lường như hoisting (khai báo được đưa lên đầu) và scope toàn cục hoặc cục bộ hàm. ES6 giới thiệu letconst, mang lại block scope (biến chỉ tồn tại trong khối {} chứa nó), giúp mã nguồn trở nên dễ đoán và ít lỗi hơn.

  • let: Cho phép khai báo biến có thể gán lại giá trị.
  • const: Dùng để khai báo hằng số, giá trị của nó không thể thay đổi sau lần gán đầu tiên.
let name = 'Alice'
name = 'Bob' // Hợp lệ

const PI = 3.14
// PI = 3.14159; // Lỗi!

Arrow Functions: Cú pháp ngắn gọn, this trực quan

Hàm mũi tên (arrow function) cung cấp một cú pháp ngắn gọn hơn để viết hàm, đặc biệt hữu ích cho các hàm ẩn danh. Quan trọng hơn, nó không tạo ra this của riêng mình mà kế thừa this từ context (ngữ cảnh) bao quanh nó, giải quyết được nhiều vấn đề nhức nhối liên quan đến this trong các hàm thông thường.

// Hàm thông thường
function add(a, b) {
  return a + b
}

// Hàm mũi tên
const add = (a, b) => a + b

Template Literals: Chuỗi thông minh hơn

Việc nối chuỗi và nhúng biến vào chuỗi trở nên đơn giản và dễ đọc hơn bao giờ hết với Template Literals, sử dụng dấu backtick (`) thay vì dấu nháy đơn hay nháy kép.

const userName = 'John'
const greeting = `Xin chào, ${userName}!`
console.log(greeting) // "Xin chào, John!"

Destructuring, Rest & Spread: Bậc thầy thao tác dữ liệu

Việc thao tác với dữ liệu giờ đây cũng đã tiện lợi hơn rất nhiều.

  • Destructuring Assignment: "Phá vỡ" cấu trúc của object hoặc array để lấy ra các giá trị cần thiết một cách nhanh chóng.
  • Rest Parameters: Gom nhiều đối số thành một mảng duy nhất.
  • Spread Operator: "Trải" các phần tử của một mảng hoặc các thuộc tính của một object ra.
// Destructuring
const person = { name: 'Jane', age: 30 }
const { name, age } = person

// Rest & Spread
const numbers = [1, 2, 3, 4, 5]
const [one, two, ...rest] = numbers // Rest
const newNumbers = [0, ...numbers, 6] // Spread

Modules, Classes và Promises: Nâng tầm JavaScript

Những tính năng tuyệt vời này thực sự giúp JavaScript vươn lên một tầm cao mới, đủ sức đứng ngang hàng với các ngôn ngữ lập trình hiện đại khác.

  • Modules (import/export): ES6 mang đến hệ thống module chính thức, cho phép chia nhỏ mã nguồn thành các file riêng biệt và tái sử dụng chúng, một tính năng cơ bản của các ngôn ngữ lập trình hiện đại.
  • Classes: Cung cấp một cú pháp "syntactic sugar" sạch sẽ và quen thuộc hơn cho việc tạo các đối tượng và xử lý kế thừa, thay vì phải thao tác trực tiếp với prototype.
  • Promises: Chuẩn hóa cách xử lý các hoạt động bất đồng bộ, giúp thoát khỏi "callback hell" và viết code bất đồng bộ dễ đọc, dễ quản lý hơn.

ES7 (ECMAScript 2016) & ES8 (ECMAScript 2017): Hoàn thiện trải nghiệm

Sau cuộc cách mạng của ES6, các phiên bản tiếp theo tập trung vào việc bổ sung và hoàn thiện các tính năng.

Array includes() Method

Một cách đơn giản và trực quan để kiểm tra xem một phần tử có tồn tại trong mảng hay không, Array.prototype.includes() trả về true hoặc false.

const animals = ['cat', 'dog', 'mouse']
console.log(animals.includes('dog')) // true

async/await: Viết code bất đồng bộ như đồng bộ

Đây là một trong những tính năng được mong chờ nhất. async/await được xây dựng dựa trên Promises, cho phép bạn viết code bất đồng bộ với cú pháp trông giống như mã đồng bộ, giúp mã nguồn trở nên cực kỳ dễ đọc và dễ hiểu.

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data')
    const data = await response.json()
    console.log(data)
  } catch (error) {
    console.error('Lỗi:', error)
  }
}

Object.values() và Object.entries()

Các phương thức hữu ích để lấy ra một mảng chứa các giá trị (Object.values) hoặc các cặp [key, value] (Object.entries) từ một object.

ES9 (ECMAScript 2018) đến ES11 (ECMAScript 2020): Các tiện ích mạnh mẽ

Rest/Spread cho Objects

Tính năng Rest và Spread được mở rộng để hoạt động với cả object, giúp việc sao chép và kết hợp object trở nên dễ dàng.

const defaults = { mode: 'light', volume: 50 }
const custom = { mode: 'dark', notification: true }

const settings = { ...defaults, ...custom }
// { mode: 'dark', volume: 50, notification: true }

Promise finally() Method

Promise.prototype.finally() cho phép thực thi một đoạn mã sau khi một Promise kết thúc, bất kể nó được giải quyết (fulfilled) hay bị từ chối (rejected).

Array flat() Method

  • flat(): Tạo một mảng mới bằng cách "làm phẳng" các mảng con lồng nhau đến một độ sâu nhất định.
  • flatMap(): Tương tự như map() nhưng sau đó tự động flat() kết quả với độ sâu là 1.

Optional Chaining (?.)

Một "vị cứu tinh" thực sự! Optional chaining cho phép bạn truy cập an toàn vào các thuộc tính lồng nhau của một đối tượng mà không cần kiểm tra từng cấp có tồn tại hay không. Nếu một tham chiếu là null hoặc undefined, biểu thức sẽ dừng lại và trả về undefined.

const user = {
  info: {
    // address: { street: '123 ABC' }
  },
}

// Thay vì: if (user && user.info && user.info.address)
const street = user.info?.address?.street // undefined

Nullish Coalescing Operator (??)

Toán tử này trả về toán hạng bên phải khi toán hạng bên trái là null hoặc undefined (chứ không phải các giá trị "falsy" khác như 0, '', false).

const volume = 0
const currentVolume = volume ?? 50 // 0 (vì 0 không phải null/undefined)

ES12 (ECMAScript 2021): Hướng tới tương lai

Các phiên bản JavaScript mới nhất tiếp tục mang lại những cải tiến đáng giá.

String replaceAll() Method

String.prototype.replaceAll() cung cấp một cách đơn giản để thay thế tất cả các lần xuất hiện của một chuỗi con trong một chuỗi, không cần dùng đến biểu thức chính quy (Regex).

Promise.any() Method

Promise.any() nhận vào một mảng các Promises và trả về ngay khi có bất kỳ Promise nào trong đó được giải quyết thành công. Nếu tất cả đều thất bại, nó sẽ trả về một AggregateError.

Các phương thức mảng không làm thay đổi mảng gốc

Các phương thức mới như toSorted(), toReversed(), và toSpliced() được giới thiệu. Chúng hoạt động tương tự như các phiên bản cũ (sort(), reverse(), splice()) nhưng thay vì thay đổi mảng ban đầu, chúng trả về một mảng mới đã được sửa đổi, phù hợp với xu hướng lập trình bất biến (immutability).

Array at() Method

Array.prototype.at() cung cấp một cách dễ dàng để truy cập các phần tử từ cuối mảng bằng cách sử dụng chỉ số âm, tương tự như trong Python.

const arr = [10, 20, 30, 40]
console.log(arr.at(-1)) // 40

Kết luận: JavaScript đang không ngừng phát triển

Hành trình qua các tính năng của ES6+ cho thấy JavaScript không ngừng phát triển và hoàn thiện. Việc nắm bắt và áp dụng những công cụ hiện đại này không chỉ giúp bạn viết code tốt hơn, mà còn mở ra những khả năng mới và giữ cho kỹ năng của bạn luôn sắc bén trong thế giới lập trình web luôn thay đổi.

Đừng ngần ngại, hãy bắt đầu sử dụng ES6+ ngay hôm nay và cảm nhận sự khác biệt!

Bài viết liên quan

[JS Basics] Phân biệt Shallow Copy và Deep Copy trong JavaScript

Bạn có chắc đã sao chép đối tượng đúng cách? Tìm hiểu sâu về Shallow copy và Deep copy trong JavaScript qua ví dụ minh họa, từ đó lựa chọn phương pháp phù hợp cho ứng dụng của mình.

[JS Basics] Cách thiết lập môi trường chạy mã JavaScript

Bạn là người mới học lập trình và muốn bắt đầu với JavaScript? Bài viết này sẽ hướng dẫn bạn từng bước cách thiết lập môi trường chạy JavaScript trên máy tính một cách dễ dàng và nhanh chóng nhất.

[JS Basics] Toán tử trong JavaScript: Tổng hợp và ví dụ thực hành dễ hiểu

Bạn muốn làm chủ JavaScript? Hãy bắt đầu bằng cách nắm vững các toán tử cơ bản. Hướng dẫn chi tiết này sẽ giúp bạn làm quen với các loại toán tử phổ biến nhất, từ số học đến logic, với các ví dụ thực tế.

[JS Basics] Câu lệnh điều kiện trong JavaScript: Ví dụ & cách dùng hiệu quả

Nắm vững các câu lệnh điều kiện phổ biến trong JavaScript như if, if-else, switch. Hướng dẫn chi tiết từ cú pháp đến cách áp dụng trong các dự án thực tế.