Học bằng cách đọc theo thứ tự

let và const — Kiểm Soát Gán Lại và Khai Báo Lại

Học khai báo biến bằng cách chọn giữa const và let: gán lại, khai báo lại, TypeError và tên camelCase.

Dù bạn đang tính tổng một đơn hàng hay hiển thị tên người dùng đã đăng nhập, bạn cần đặt tên cho một giá trị để tham chiếu nó nhiều lần. Cái tên đó là một biến (variable) (một cái tên gắn với một giá trị — viết cái tên, bạn nhận lại cùng một giá trị).

JavaScript cho bạn hai cách tạo biến, constlet, và bạn chọn cái nào sẽ quyết định liệu bạn có thể thay giá trị khác vào sau này hay không.

Đặt Tên Cho Giá Trị — Chọn Giữa const và let

Viết cùng một giá trị trực tiếp ở nhiều chỗ trong code, và bạn sẽ phải lùng sục từng chỗ khi nó cần thay đổi. Hãy đặt tên cho các giá trị như đơn giá hoặc thuế suất ngay từ đầu, rồi tham chiếu cái tên đó từ đó về sau.

Dòng bạn đặt tên cho nó gọi là một khai báo (declaration) (dòng tạo ra tên của một biến và cho nó giá trị đầu tiên).

Một khai báo trong JavaScript quyết định, ngay khi tạo tên đó, liệu nội dung của tên đó có thể được thay sau này hay không. Dùng const nếu không, let nếu có.

Đặt một giá trị khác vào một tên đã khai báo gọi là gán lại (reassignment) (cho một tên đã khai báo một giá trị khác về sau). Một tên khai báo bằng const không thể gán lại, nên mặc định hữu ích là viết const trước, và chỉ chuyển sang let khi có dòng cần gán lại nó.

const và let Làm Được Gì
Loại khai báoGán lạigiá trị mớiKhai báo lạicùng tênconstKhôngTypeErrorKhôngSyntaxErrorletKhôngSyntaxError
Gán lại (đặt một giá trị khác vào cùng một tên) — chỉ let làm được. Khai báo lại (khai báo lại cùng tên) — cả hai đều không. TypeErrorSyntaxError là gì sẽ nói ở phần sau.

const — Cho Các Giá Trị Bạn Sẽ Không Thay Đổi

const cố định một giá trị ngay tại dòng bạn khai báo, và tên đó không bao giờ nhận giá trị khác sau đó. Những thứ như tên sản phẩm, đơn giá, hay thuế suất — các giá trị giữ nguyên khi chương trình tiếp tục chạy — thuộc nhóm này, và hầu hết giá trị trong một chương trình đều vậy.

Một chuỗi ký tự bọc trong dấu ngoặc kép, như "Insulated Mug", gọi là chuỗi (string), và một con số như 1200number. Cả hai được giải thích chi tiết ở bài 3 và bài 4.

console.log, xuất hiện trong ví dụ code tiếp theo, là lệnh in ra bất kỳ giá trị nào bạn truyền vào, trong dấu ngoặc, ra màn hình kết quả dưới dạng văn bản. Console của trang này không có màn hình, nên bạn truyền vào bất kỳ giá trị nào bạn muốn kiểm tra.

Mọi thứ từ // đến cuối dòng là một comment (văn bản giải thích để lại trong code, không bao giờ chạy) và sẽ không xuất hiện trong kết quả. Những dòng như // ① xuất hiện sẵn trong bài tập cũng là loại ghi chú này.

// Giá trị bạn sẽ không thay đổi thì dùng const
const productName = "Insulated Mug";
const unitPrice = 1200;

console.log(productName);   // Insulated Mug
console.log(unitPrice);     // 1200

Lưu một sản phẩm của cửa hàng online vào biến rồi hiển thị nó.

① Khai báo productName là "Insulated Mug", unitPrice là 1200, và quantity là 3, tất cả bằng const.

② Hiển thị nội dung của productName.

③ Tính thành tiền từ đơn giá và số lượng, rồi hiển thị.

(Nếu chạy đúng, phần giải thích sẽ xuất hiện.)

JavaScript / TypeScript Editor

Chạy code để xem đầu ra

let — Biến Bạn Sẽ Thay Giá Trị Vào Sau

Dùng let cho những thứ như số lượng tồn kho hay tổng đang chạy — các giá trị mà nội dung thay đổi khi chương trình tiếp tục. Vế phải của = đọc giá trị hiện tại y nguyên, nên bạn có thể đọc giá trị hiện tại, tính toán với nó, rồi gán lại kết quả vào cùng tên đó.

let orderTotal = 0;

orderTotal = orderTotal + 1200;  // Đọc 0 hiện tại, cộng 1200, gán lại
orderTotal = orderTotal + 400;   // Đọc 1200 hiện tại, cộng 400, gán lại

console.log(orderTotal);         // 1600

Số lượng tồn kho của một kho hàng thay đổi mỗi lần xuất/nhập hàng. stockCount đã được khai báo bằng let.

① Sau khi xuất hàng làm giảm tồn kho 3 đơn vị, gán lại số mới cho stockCount và hiển thị.

② Sau đó, sau khi nhập hàng thêm 10, gán lại số mới cho stockCount và hiển thị.

JavaScript / TypeScript Editor

Chạy code để xem đầu ra

Gán Lại vs Khai Báo Lại — Hai Lỗi Làm Dừng Chương Trình

Chọn const nghĩa là quyết định, ngay trong code, rằng nội dung của tên này sẽ không bao giờ thay đổi.

Gán cho nó một giá trị khác sau đó, JavaScript dừng chương trình ngay tại dòng đó và ném ra TypeError (lỗi khi dùng một giá trị sai cách). Không có gì sau dòng đó chạy nữa.

Điều Gì Xảy Ra Khi Gán Sau Khi Khai Báo
const price= 1200Tên gắnvới giá trịHiện 1200price = 1500Dừngngay đóTypeErrorlet quantity = 2quantity = 3Chuyển sanggiá trị mớiHiện 3thử gán
2 hàng trên là một luồng cho const; hàng dưới là luồng cho let. const dừng ngay dòng gán; let cứ tiếp tục sang dòng kế.

Cách khác làm dừng chương trình là khai báo lại (redeclaration) (khai báo lại một tên đã dùng trong cùng phạm vi). Cả const lẫn let đều không cho phép — bạn nhận SyntaxError (lỗi cho code hoàn toàn không đúng ngữ pháp của ngôn ngữ).

Điều này bắt lỗi gõ nhầm tên, hoặc một tên vô tình dùng lại cho thứ khác, ngay lập tức.

let cartQuantity = 1;
let cartQuantity = 2;
// SyntaxError: Identifier 'cartQuantity' has already been declared

Nếu bạn chỉ muốn thay giá trị vào, chỉ khai báo một lần, rồi gán vào tên đó ở mọi dòng sau. Một dòng không có từ khóa khai báo là gán lại, nên với let nó sẽ không làm dừng chương trình.

let itemQuantity = 1;

itemQuantity = 2;            // Không có từ khóa khai báo, nên đây là gán lại
console.log(itemQuantity);   // 2

Các Lỗi Xuất Hiện Ở Thời Điểm Khác Nhau

TypeError từ gán lại xuất hiện ngay tại dòng đó, khi chương trình chạy đến, nên bất cứ thứ gì chạy trước nó vẫn hiện trong kết quả.

SyntaxError từ khai báo lại xuất hiện trong lúc code đang được phân tích, nên không gì chạy cả, kể cả dòng 1. Nếu bạn không thấy kết quả nào cả, hãy nghi ngờ lỗi cú pháp trước tiên.

Các giá trị không đổi, như thuế suất, được khai báo bằng const. Code dưới đây cố gán lại thuế suất đó sau. Chạy nguyên bản và xem nó chạy được đến đâu và thông báo gì làm nó dừng lại. (Lần này bạn chỉ chạy code và đọc kết quả — không sửa.)

JavaScript / TypeScript Editor

Chạy code để xem đầu ra

Đặt Tên Biến — camelCase và Ký Tự Được Phép

Tên biến là nơi bạn cho người đọc biết giá trị thực sự là gì. Những tên như a hay data bắt bạn phải quay lại dòng khai báo mỗi lần đọc một dòng ở xa. Những tên như unitPrice hay stockCount cho phép đọc thẳng nội dung từ cái tên.

Tên có thể dùng chữ cái, chữ số, dấu gạch dưới, và ký hiệu đô la, và không được bắt đầu bằng chữ số. Chữ hoa/thường được phân biệt, nên stockcountstockCount là hai biến khác nhau.

Các từ JavaScript đã gán sẵn ý nghĩa, như const / let / if (từ khóa dành riêng), không được dùng làm tên.

Tên biếnĐược / Không đượcLý do
stockCountĐượcChỉ toàn chữ cái
item2PriceĐượcChữ số ở giữa vẫn ổn nếu bắt đầu bằng chữ cái
_draftOrderĐượcBắt đầu bằng dấu gạch dưới cũng được
$priceĐượcKý hiệu đô la cũng dùng được trong tên
2ndItemKhông đượcKhông được bắt đầu bằng chữ số
item-priceKhông đượcDấu gạch ngang không phân biệt được với phép trừ
constKhông đượcTừ khóa dành riêng không được dùng làm tên

Với tên gồm hai từ trở lên, dùng camelCase (từ đầu viết thường, chỉ viết hoa chữ cái đầu của mỗi từ sau đó). priceWithTax hay orderTotal có dạng này.

Các hàm và property có sẵn của JavaScript cũng theo dạng này, nên viết theo cùng kiểu giúp tên bạn tự đặt không bị lạc lõng.

const listPrice = 1250;
const discountRate = 0.15;                 // Giảm giá 15% cho thành viên

// Tên cho biết số tiền này là gì
const discountedPrice = listPrice * (1 - discountRate);
console.log(discountedPrice);              // 1062.5

// Làm tròn xuống phần dưới 1 đô la
console.log(Math.floor(discountedPrice));  // 1062

Tính tổng tiền cho 2 đơn vị một mặt hàng thực phẩm chịu thuế suất ưu đãi 8%. unitPrice, quantity, và taxRate đã được khai báo sẵn.

① Lưu thành tiền trước thuế vào một biến đặt tên theo camelCase.

② Lưu giá đã gồm thuế — thành tiền cộng thuế — vào một tên camelCase khác, và hiển thị.

JavaScript / TypeScript Editor

Chạy code để xem đầu ra

Vì Sao Không Dùng var

Code cũ và tài liệu cũ có giới thiệu cách khai báo thứ ba, var. var cho phép khai báo lại cùng một tên bao nhiêu lần cũng được, không báo lỗi nếu bạn tham chiếu nó trước dòng khai báo, mà cứ tiếp tục với một giá trị chưa được thiết lập. Phạm vi mà một tên có hiệu lực cũng hoạt động khác với const / let.

Vì nó không báo lỗi ngay khi có sai sót, tìm ra nguyên nhân sẽ mất nhiều thời gian hơn.

Code Mới Không Dùng var

Cả const lẫn let đều báo lỗi khi khai báo lại và khi tham chiếu trước khai báo. Khóa học này cũng không dùng var từ đây trở đi. Cơ chế đầy đủ của phạm vi (scope) sẽ được nói đến ở bài về scope trong nhóm cú pháp.

Bài này đã nói về đặt tên giá trị bằng constlet, TypeError khi gán lại const, SyntaxError khi khai báo lại, và quy tắc đặt tên gồm camelCase. Giá trị bạn sẽ không thay đổi thì dùng const; chỉ giá trị sẽ thay đổi mới dùng let — lựa chọn đó sẽ theo suốt mọi đoạn code từ đây về sau.

QUIZ

Kiểm tra kiến thức

Hãy trả lời từng câu hỏi một.

Câu 1Bạn dùng khai báo nào cho một biến mà bạn không định gán lại sau khi khai báo?

Câu 2Điều gì xảy ra khi bạn chạy đoạn code này?
const unitPrice = 1200;
unitPrice = 1500;
console.log(unitPrice);

Câu 3Cái nào trong số này không thể dùng làm tên biến?