Giải thích let trong JavaScript: Sự khác biệt giữa let, var và const (Hướng dẫn từ cơ bản đến trung cấp)

目次

1. Giới thiệu

Việc khai báo biến trong JavaScript là một trong những khái niệm cơ bản nhất trong lập trình. Trong những năm gần đây, ba từ khóa khai báo khác nhau — var, letconst — đã trở nên phổ biến, khiến việc lựa chọn từ khóa phù hợp cho mỗi tình huống trở nên quan trọng.

Trong bài viết này, chúng tôi tập trung vào từ khóa “javascript let” và giải thích rõ ràng đặc điểm và cách sử dụng let, cũng như sự khác biệt của nó so với varconst. Nội dung được thiết kế cho người mới bắt đầu đến các nhà phát triển trung cấp, bao quát mọi thứ từ khái niệm cơ bản đến việc sử dụng thực tế.

Mục tiêu của chúng tôi là giúp độc giả hiểu chính xác khi nào và tại sao nên dùng let, từ đó viết mã JavaScript an toàn, hiệu quả và dễ bảo trì.

2. Tổng quan về các phương pháp khai báo biến trong JavaScript

Trong JavaScript, biến được dùng để tạm thời lưu trữ dữ liệu. Có ba từ khóa chính để khai báo biến:

  • var: Phương pháp khai báo biến truyền thống được sử dụng trong các phiên bản JavaScript cũ
  • let: Một từ khóa khai báo biến có phạm vi khối, được giới thiệu trong ES6 (ECMAScript 2015)
  • const: Từ khóa khai báo hằng số, cũng được giới thiệu trong ES6

Mỗi từ khóa này có những đặc điểm khác nhau, vì vậy việc lựa chọn phù hợp tùy thuộc vào mục đích và ngữ cảnh sử dụng.

Bảng dưới đây tóm tắt các tính năng cơ bản của chúng:

KeywordScopeRedeclarationReassignmentPrimary Use Case
varFunction scopeAllowedAllowedLegacy code and backward compatibility
letBlock scopeNot allowedAllowedTemporary variables and dynamic data handling
constBlock scopeNot allowedNot allowedManaging constants and fixed values

Như được thể hiện trong bảng, let được sử dụng rộng rãi như một cách khai báo biến linh hoạt, hỗ trợ phạm vi khối và cho phép gán lại, phù hợp với nhiều kịch bản JavaScript hiện đại.

3. let là gì? — Cách sử dụng cơ bản

let là một từ khóa khai báo biến mới được giới thiệu trong ES6. Nó chủ yếu có các đặc điểm sau.

  1. Có phạm vi khối
  2. Cho phép gán lại
  3. Hành vi hoisting khác với var

3.1 Cú pháp cơ bản của let

Đoạn mã dưới đây cho thấy cách khai báo biến cơ bản bằng let.

let x = 10;  // Declare variable x and assign the value 10
x = 20;      // Reassignment is allowed
console.log(x); // Output: 20

Như bạn thấy trong ví dụ này, let cho phép bạn thay đổi giá trị sau khi khai báo. Điều này khác với const, và làm cho let phù hợp cho việc quản lý dữ liệu linh hoạt.

3.2 Đặc điểm của phạm vi khối

letphạm vi khối, nó chỉ hợp lệ trong khối mà nó được khai báo.

{
  let y = 30;  // Declared inside the block
  console.log(y); // Output: 30
}
console.log(y); // Error: y is not defined

Theo cách này, biến y không thể được tham chiếu bên ngoài khối, dẫn đến lỗi. Điều này giúp ngăn ngừa việc ô nhiễm toàn cục không mong muốn và cho phép quản lý biến an toàn hơn.

3.3 Hành vi hoisting

let được hoist, nhưng việc truy cập nó trước khi khai báo sẽ gây ra lỗi.

console.log(z); // Error: Cannot access 'z' before initialization
let z = 50;

Hành vi này trái ngược với var, vốn được khởi tạo là undefined trong quá trình hoisting. Để tránh lỗi, luôn sử dụng let sau khi nó đã được khai báo.

4. Sự khác biệt giữa varlet

Trong JavaScript, bạn có thể khai báo biến bằng var hoặc let, nhưng có một số khác biệt quan trọng giữa chúng. Trong phần này, chúng tôi tập trung vào phạm vi, việc khai báo lại và hành vi hoisting, và giải thích chi tiết các khác biệt bằng các ví dụ cụ thể.

4.1 Khác biệt về phạm vi

Một điểm khác biệt then chốt là var có phạm vi hàm, trong khi let có phạm vi khối.

Ví dụ về phạm vi hàm (var)

function exampleVar() {
  if (true) {
    var a = 10; // Variable declared inside the function
  }
  console.log(a); // Output: 10
}

exampleVar();

Ví dụ về phạm vi khối (let)

function exampleLet() {
  if (true) {
    let b = 20; // Valid only within the block
  }
  console.log(b); // Error: b is not defined
}

exampleLet();

Do sự khác biệt này, let phù hợp hơn trong việc ngăn ngừa việc định nghĩa lại hoặc ghi đè biến một cách không mong muốn.

4.2 Có cho phép khai báo lại hay không

var có thể được khai báo lại trong cùng một phạm vi, nhưng let không cho phép khai báo lại.

Ví dụ khai báo lại với var

var x = 10;
var x = 20; // Redeclaration is allowed without issues
console.log(x); // Output: 20

Ví dụ khai báo lại với let

let y = 10;
let y = 20; // Error: Identifier 'y' has already been declared
console.log(y);

Với đặc điểm này, let giúp ngăn ngừa các lỗi khi cùng một biến bị khai báo một cách vô tình nhiều lần.

4.3 Sự khác biệt về Hoisting

Hoisting là một cơ chế của JavaScript mà trong đó các khai báo biến và hàm được đưa lên đầu phạm vi của chúng.

Ví dụ Hoisting với var

console.log(z); // Output: undefined
var z = 30;

Ví dụ Hoisting với let

console.log(w); // Error: Cannot access 'w' before initialization
let w = 40;

4.4 Tóm tắt cách sử dụng

var được sử dụng cho mã cũ hoặc khi cần tính tương thích ngược, trong khi let được dùng trong mã hiện đại để đạt được quản lý phạm vi an toàn hơn.

Bảng so sánh

Featurevarlet
ScopeFunction scopeBlock scope
RedeclarationAllowedNot allowed
ReassignmentAllowedAllowed
Access before initializationundefinedReferenceError
Recommended usageLegacy code and compatibilityModern code and safe variable management

5. Sự khác nhau giữa constlet

Trong JavaScript, const là một phương pháp khai báo biến thường được sử dụng khác bên cạnh let. Trong phần này, chúng ta sẽ xem xét kỹ hơn sự khác nhau giữa letconst và giải thích cách sử dụng mỗi loại một cách phù hợp.

5.1 const là gì?

constmột từ khóa dùng để khai báo các biến không thể được gán lại.

Cú pháp cơ bản

const pi = 3.14; // Declare a constant
pi = 3.14159;    // Error: Assignment to constant variable.

Trong ví dụ này, giá trị của pi không thể thay đổi sau khi khai báo, và việc cố gắng gán lại sẽ gây ra lỗi.

5.2 Sự khác nhau giữa letconst

Featureletconst
ScopeBlock scopeBlock scope
ReassignmentAllowedNot allowed
RedeclarationNot allowedNot allowed
Initialization requiredNot required (declaration only is allowed)Required (must be initialized at declaration)
Recommended usageVariables whose values may changeConstants and immutable data references

5.3 So sánh Gán lại và Khai báo lại

Ví dụ Gán lại với let

let count = 1;  // Initialization
count = 2;      // Reassignment is allowed
console.log(count); // Output: 2

Ví dụ Gán lại với const

const maxCount = 10;
maxCount = 20; // Error: Assignment to constant variable.

Như đã chỉ ra ở trên, let phù hợp cho việc xử lý các giá trị thay đổi, trong khi const là tốt nhất cho các giá trị cố định.

5.4 Lưu ý quan trọng cho Đối tượng và Mảng

Mặc dù const ngăn không cho gán lại, các thuộc tính của đối tượng và các phần tử của mảng vẫn có thể được sửa đổi.

Ví dụ Đối tượng

const user = { name: "Taro" };
user.name = "Jiro"; // Modifying properties is allowed
console.log(user.name); // Output: "Jiro"

user = { name: "Saburo" }; // Error: Reassignment is not allowed

Ví dụ Mảng

const numbers = [1, 2, 3];
numbers.push(4); // Adding elements is allowed
console.log(numbers); // Output: [1, 2, 3, 4]

numbers = [5, 6, 7]; // Error: Reassignment is not allowed

5.5 Các ví dụ thực tế

Các trường hợp nên dùng const:

  1. Hằng số hoặc giá trị không bao giờ thay đổi
    const TAX_RATE = 0.1;
    
  1. Khi cố định tham chiếu tới các đối tượng hoặc mảng
    const CONFIG = {
      apiUrl: "https://example.com/api",
    };
    

Các trường hợp nên dùng let:

  1. Khi các giá trị cần thay đổi một cách động
    let count = 0;
    count++;
    
  1. Các biến được tăng trong vòng lặp
    for (let i = 0; i < 10; i++) {
      console.log(i);
    }
    

6. Khi nào nên dùng let và các lưu ý quan trọng

JavaScript cung cấp ba tùy chọn khai báo biến: var, letconst. Trong số đó, let đóng một vai trò đặc biệt hữu ích trong một số tình huống.

Trong phần này, chúng tôi sẽ giải thích khi nào bạn nên sử dụng let và những điểm quan trọng cần lưu ý.

6.1 Các trường hợp đề xuất sử dụng let

  1. Khi cần phạm vi khối (block scope)letphạm vi khối, nó cho phép quản lý biến một cách an toàn trong các câu lệnh điều kiện và vòng lặp. Ví dụ: Quản lý biến trong một khối điều kiện
    if (true) {
      let message = "Hello, World!";
      console.log(message); // Output: Hello, World!
    }
    console.log(message); // Error: message is not defined
    
  1. Khi giá trị cần được cập nhật một cách động const không cho phép gán lại, nhưng let phù hợp cho các trường hợp giá trị thay đổi động. Ví dụ: Quản lý biến trong một vòng lặp
    let total = 0;
    for (let i = 1; i <= 5; i++) {
      total += i;
    }
    console.log(total); // Output: 15
    
  1. Khi lưu trữ các giá trị tạm thời Đối với các biến chỉ được sử dụng trong thời gian ngắn trong một hàm, let cải thiện khả năng đọc và bảo trì mã. Ví dụ: Các biến cục bộ trong một hàm
    function calculateDiscount(price) {
      let discount = 0.1; // Temporary discount rate
      return price * (1 - discount);
    }
    console.log(calculateDiscount(1000)); // Output: 900
    

6.2 Những điểm cần lưu ý khi sử dụng let

  1. Cẩn thận với việc khởi tạo biến Truy cập một biến let trước khi nó được khai báo sẽ gây ra lỗi. Ví dụ: Truy cập trước khi khởi tạo
    console.log(a); // Error: Cannot access 'a' before initialization
    let a = 10;
    
  1. Hiểu hành vi hoisting Mặc dù let được hoist, nhưng không thể truy cập được trong “Temporal Dead Zone (TDZ).” Ví dụ: Hành vi TDZ
    if (true) {
      console.log(b); // Error: Cannot access 'b' before initialization
      let b = 20;
    }
    
  1. Nhận thức về ranh giới phạm vi Bạn không thể khai báo lại một biến cùng tên trong cùng một khối. Ví dụ: Lỗi khai báo lại
    let c = 10;
    let c = 20; // Error: Identifier 'c' has already been declared
    
  1. Sử dụng let để tránh ô nhiễm toàn cục Việc dùng var làm tăng nguy cơ ảnh hưởng tới phạm vi toàn cục, trong khi let giúp giảm rủi ro này. Ví dụ: Tránh xung đột giữa biến toàn cục và biến cục bộ
    let d = 50; // Global variable
    function test() {
      let d = 30; // Local variable
      console.log(d); // Output: 30
    }
    test();
    console.log(d); // Output: 50
    

7. Phần Câu hỏi Thường gặp (FAQ)

Trong phần này, chúng tôi tóm tắt các câu hỏi và câu trả lời phổ biến liên quan đến let trong JavaScript. Các mối quan tâm thực tiễn và giải pháp cho các vấn đề thường gặp được giải thích kèm theo các ví dụ cụ thể.

Hỏi 1: Tại sao tôi nên dùng let?

Đáp:
let được khuyến nghị vì các lý do sau.

  1. Phạm vi khối:let giới hạn phạm vi biến trong một khối, nó ngăn ngừa việc ghi đè không mong muốn lên các biến.
  2. Ngăn chặn khai báo lại: Việc khai báo lại trong cùng một phạm vi không được phép, giảm nguy cơ lỗi.
  3. An toàn với hoisting: let ném lỗi trong Temporal Dead Zone (TDZ), giúp dễ dàng phát hiện các sai lầm khi biến được truy cập trước khi khai báo.

Hỏi 2: Những vấn đề nào xảy ra khi dùng var?

Đáp:
Mặc dù var duy trì tính tương thích với mã cũ, nó có những vấn đề sau.

  1. Phạm vi quá rộng: Vì chỉ có phạm vi hàm, các biến được khai báo bên trong khối có thể vô tình được truy cập bên ngoài.
    if (true) {
      var x = 10;
    }
    console.log(x); // Output: 10
    
  1. Cho phép khai báo lại: Điều này có thể dẫn đến việc ghi đè vô tình lên các biến.
    var y = 20;
    var y = 30; // Overwriting occurs
    
  1. Hành vi hoisting: Các biến khai báo bằng var được khởi tạo là undefined, cho phép truy cập trước khi khởi tạo.
    console.log(z); // Output: undefined
    var z = 50;
    

Hỏi 3: Làm sao chọn giữa letconst?

Đáp:
Nguyên tắc cơ bản như sau.

  • const: Dùng khi giá trị không nên thay đổi hoặc khi coi nó là hằng số.
  • let: Dùng khi giá trị có thể thay đổi hoặc cần được cập nhật một cách động.

Ví dụ:

.

const TAX_RATE = 0.1;
let price = 1000;
price = price * (1 + TAX_RATE); // Price calculation

Việc chọn từ khóa phù hợp dựa trên tính chất của dữ liệu giúp mã của bạn diễn đạt rõ ràng hơn và dễ hiểu hơn.

Câu hỏi 4: Nguyên nhân gây ra ReferenceError khi truy cập let trước khi khởi tạo?

Đáp:
Các biến được khai báo bằng let được hoist, nhưng chúng không thể được truy cập trong “Temporal Dead Zone (TDZ).”

Ví dụ:

console.log(a); // Error: Cannot access 'a' before initialization
let a = 10;

Giải pháp:
Khai báo và khởi tạo biến cùng lúc, và chú ý tới thứ tự của mã.

8. Kết luận

Trong bài viết này, chúng tôi đã giải thích chi tiết về let trong khai báo biến JavaScript. Chúng tôi đã đề cập đến cách sử dụng cơ bản, sự khác biệt so với varconst, các ví dụ thực tế, và trả lời các câu hỏi thường gặp.

Dưới đây là bản tóm tắt ngắn gọn các điểm chính đã được thảo luận.

8.1 Đặc điểm chính của let

  1. Có phạm vi khối (block scope):
  • let chỉ hợp lệ trong một khối ({}).
  • Điều này ngăn ngừa việc ghi đè biến không mong muốn.
  1. Cho phép gán lại giá trị:
  • Thích hợp cho các vòng lặp và logic điều kiện nơi giá trị thay đổi động.
  1. Không cho phép khai báo lại:
  • Tăng cường độ an toàn của mã bằng cách ngăn ngừa khai báo trùng lặp.
  1. Hành vi hoisting:
  • Các khai báo được hoist, nhưng việc truy cập biến trước khi khởi tạo sẽ gây lỗi do TDZ.

8.2 So sánh với các phương pháp khai báo khác

Featurevarletconst
ScopeFunction scopeBlock scopeBlock scope
RedeclarationAllowedNot allowedNot allowed
ReassignmentAllowedAllowedNot allowed
Access before initializationundefinedErrorError
Typical use caseLegacy compatibilityDynamic data handlingConstants and fixed values

8.3 let hữu ích nhất ở đâu

let đặc biệt hiệu quả trong các kịch bản sau.

  • Câu lệnh điều kiện và vòng lặp: Dùng khi giá trị thay đổi động.
    for (let i = 0; i < 5; i++) {
      console.log(i);
    }
    
  • Biến cục bộ trong hàm: Lý tưởng để lưu trữ các giá trị tạm thời.
    function calculateTotal(price) {
      let discount = 0.1;
      return price * (1 - discount);
    }
    
  • Quản lý trạng thái động: Hữu ích khi giá trị thay đổi dựa trên đầu vào của người dùng hoặc trạng thái ứng dụng.
    let userInput = prompt("Please enter your name:");
    console.log(`Hello, ${userInput}!`);
    

8.4 Thực hành tốt và lưu ý

  1. Tránh truy cập biến trước khi khai báo: Khai báo biến sớm để ngăn lỗi liên quan đến hoisting.
  2. Ưu tiên const, và chỉ dùng let khi cần gán lại: Điều này cải thiện tính rõ ràng và an toàn của mã.
  3. Cẩn thận trong quản lý phạm vi: Luôn xem xét phạm vi của biến để tránh truy cập hoặc xung đột không mong muốn.

8.5 Tóm tắt cuối cùng

let là một lựa chọn linh hoạt và an toàn cho việc khai báo biến trong lập trình JavaScript hiện đại.

  • Chỉ dùng var cho mã legacy; ưu tiên let hoặc const trong các dự án mới.
  • Dùng let cho các giá trị thay đổi và const cho các giá trị cố định để cải thiện khả năng đọc và độ tin cậy.

8.6 Các bước tiếp theo

Áp dụng những gì bạn đã học bằng cách thực hành với mã thực tế. Bạn cũng có thể tham khảo các chủ đề sau đây để tiếp tục nâng cao kiến thức.

  1. Kiểu dữ liệu JavaScript và chuyển đổi kiểu – Sâu hơn về quản lý dữ liệu.
  2. Hàm và phạm vi chi tiết – Thành thạo kiểm soát phạm vi nâng cao và thiết kế hàm.
  3. Tổng quan về ES6 và các tính năng sau này – Khám phá các khả năng hiện đại của JavaScript.
広告