Điểm lại những tính năng sắp có của Javascript trong ECMAScript 2022 (ES13)

Điểm lại những tính năng sắp có của Javascript trong ECMAScript 2022 (ES13)

Tin ngắn hàng ngày dành cho bạn
  • Ái chà, Windsurf vừa mới cập nhật chính sách mới cho tài khoản miễn phí mọi người ạ. Có 3 điều nổi bật nhất là:

    • 25 credits mỗi tháng để sử dụng model cao cấp như gpt-4, sonet 3.5...
    • Sử dụng không giới hạn chế độ Write (giống Agents của Cursor) với model cây nhà lá vườn Cascade Base của họ.
    • Không giới hạn gợi ý mã, đặc biệt là với tốc độ nhanh luôn (đợt trước bị giới hạn ở tốc độ chậm).

    Đáng để quay lại nhỉ mọi người 🤤

    » Xem thêm
  • Deep Research Mini đã bắt đầu xuất hiện trong tài khoản GPT miễn phí của mình rồi nè. Đây có thể coi như là một phiên bản rút gọn của tính năng Deep Research vốn chỉ có trong tài khoản GPT trả phí.

    Mình vừa thử với một lệnh "Tình hình tiêu thụ cà phê ở Việt Nam trong năm 2024", nó tự đi tìm và tổng hợp tài liệu mất 34 phút và cho ra một bản báo cáo trông khá chỉn chu. Tính năng này coi bộ hữu ích đây, phải dùng thêm nữa mới biết được 🤤

    À gọi là mini vì nó dùng mô hình 4o-mini và hiện tại thì mỗi tháng chỉ được dùng 5 lượt thôi á 🫣

    » Xem thêm
  • R1 chưa qua, R2 đã tới 😅

    Mặc dù mới đang đồn thổi thôi cơ mà chắc chỉ có Deepseek mới gây tiếng vang tương tự như OpenAI hoặc Anthropic. Mà thứ người dùng quan tâm là chất lượng & giá cả 😄

    Deepseek R2 will be releasing soon

    » Xem thêm

Vấn đề

Đến hẹn lại lên, kể từ năm 2016 ECMAScript đã cam kết mỗi năm sẽ phát hành một phiên bản của Javascript với những cải tiến và thêm những tính năng mới. Đến hiện tại là năm 2022 và chúng ta sắp có những tính năng gì? Hãy cũng điểm lại một số điểm nổi bật nhé.

Private slots

Javascript đã hỗ trợ cú pháp kiểu khai báo Class đã lâu tuy nhiên vẫn còn nhiều thiếu sót. Một trong những tính năng ES13 mang tới sẽ là thuộc tính private của Class.

class Person {
  #name;

  getName() {
      return this.#name;
  }

  setName(name) {
      this.#name = name;
  }
}

Với Private slots bạn sẽ không thể tự do truy cập vào thuộc tính name nữa mà phải thông qua get/set.

const p = new Person();
p.setName('2coffee.dev');
p.name; // undefined
p.getName(); // 2coffee.dev

Ngoài ra bạn có thể sử dụng hàm Object.hasOwn để xác định xem một Class có chứa một thuộc tính private xác định hay không.

Object.hasOwn(Person, 'name'); // true

Top-level await

Nếu như trước kia bạn muốn sử dụng await thì bắt buộc phải sử dụng trong một hàm async thì bây giờ bạn đã có thể sử dụng await ở bên ngoài async (top-level).

async function fetchData() {
  const resp = await fetch('https://jsonplaceholder.typicode.com/users');
  return resp.json();
}
fetchData();

# Bây giờ thì
const resp = await fetch('https://jsonplaceholder.typicode.com/users');
resp.json();

Ngoài ra tính năng này rất hữu ích với cú pháp import, như chúng ta đã biết import được thực hiện một cách bất đồng bộ giúp cho việc "tải" module nhanh hơn nhưng lại có một hạn chế là chúng ta phải viết nhiều mã hơn để đợi cho đến khi module được tải xong mới có thể sẵn sàng sử dụng các hàm có ở trong đó. Với ES13 cú pháp import sẽ hoạt động "như" đồng bộ bằng việc dùng Promise.all cho tất cả import.

Giả sử hai module first.mjs và second.mjs có export các hàm bất đồng bộ ví dụ như:

# first.mjs
async function first() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('first');
    }, 1000);
  });
}

export default first();

Sau đó sử dụng hai module trên:

import { first } from './first.mjs';
import { second } from './second.mjs';
console.log(first, second);

# sẽ tương tương như
import { promise as firstPromise, first } from './first.mjs';
import { promise as secondPromise, second } from './second.mjs';
export const promise = (async () => {
  await Promise.all([firstPromise, secondPromise]);
  console.log(first, second);
})();

Error Cause

Error cause là một cách tiếp cận mới về việc truy vết xử lý lỗi trong Javascript.
Hãy nhìn vào lấy dữ liệu sau của tôi:

const fetchData = async () => {
  return await fetch(url)
    .catch(err => {
       // Bạn sẽ làm gì với err?
    })
}

Bạn sẽ làm gì với err? Console.log ra err và ném (throw) ra một message thông báo "lấy dữ liệu thất bại"!?

const fetchData = async () => {
  return await fetch(url)
    .catch(err => {
       console.log(err);
       throw new Error('lấy dữ liệu thất bại');
    })
}

Khi gọi hàm fetchData mà có lỗi ta sẽ nhận được new Error('lấy dữ liệu thất bại') mà không thể nhận được err, đặc biệt nếu sử dụng fetchData lồng trong nhiều catch thì việc truy vết lỗi sẽ khó khăn bởi vì kết quả nhận được là một thông báo lỗi khác mà ta mong muốn chứ không phải là một err.

Giờ đây với ES13 bạn có thể sử dụng Error Cause để vừa đẩy ra new Error('lấy dữ liệu thất bại'), vừa đính kèm luôn cả err:

const fetchData = async () => {
  return await fetch(url)
    .catch(err => {
       throw new Error('lấy dữ liệu thất bại', { cause: err });
    })
}

Khi đó ta có thể lấy ra err trong fetchData theo cách:

try {
  resp = await fetchData();
  ...
} catch(e) {
  console.log('cause', e.cause);
}

Phương thức .at()

Sử dụng phương thức .at() để lấy ra phần tử tại vị trí index được gọi. Đặc biệt sử dụng index âm để lấy vị trí từ phải sang trái.

['a', 'b', 'c'].at(0); // a
['a', 'b', 'c'].at(-1); // c

Áp dụng cho tất cả Array và String.

RegExp match indices

Thêm flag /d vào regex để lấy ra vị trí bắt đầu - kết thúc của chuỗi tìm được. Vị trí này nằm trong thuộc tính indices.

const matchObj = /(a+)(b+)/d.exec('aaaabb');
console.log(matchObj.indices); // [[0, 6], [0, 4], [4, 6]]

Tổng kết

Trên đây là điểm lại một số điểm nổi bật sẽ phát hành trong ECMAScript 2022. Dự kiến ES13 sẽ được phát hành vào khoảng tháng 6/2022. Hãy cập nhật ngay!

Tham khảo:

Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (2)

Nội dung bình luận...
Avatar
Tiến Đức2 năm trước
Chỗ error kia hơi khó hiểu nhỉ
Trả lời
Avatar
Xuân Hoài Tống2 năm trước
B đọc kĩ lại xem chẳng qua là mình có thể "gắn" được error kèm trong lúc trả về error thôi :D
Avatar
Trịnh Thị Anh2 năm trước
Có ai đọc mãi mà không hiểu vụ import không ạ? Chắc mỗi t
Trả lời
Avatar
Tùng Nguyễn2 năm trước
import chạy bất đồng bộ, h c dùng await vào thì nó sẽ đồng bộ kiểu thế
Avatar
Xuân Hoài Tống2 năm trước
import là một cú pháp nhập một module theo cách bất đồng bộ vào file của bạn, chính vì bất đồng bộ nên trước kia bạn cần phải "chờ" cho mã được import xong hoàn toàn mới bắt đầu dùng được