+109

Phân biệt kiểu biến var, let, và const trong JavaScript

1. Giới Thiệu

ES6 (viết tắt của ECMAScript 6) là một tập hợp các kỹ thuật nâng cao của Javascript. ECMAScript do hiệp hội các nhà sản xuất máy tính Châu Âu đề xuất làm tiêu chuẩn của ngôn ngữ Javascript. Bạn cứ nghĩ xem hiện nay có khá nhiều trình duyệt Browser ra đời và nếu mỗi Browser lại có cách chạy Javascript khác nhau thì các trang web không thể hoạt động trên tất cả các trình duyệt đó được, vì vậy cần có một chuẩn chung để bắt buộc các browser phải phát triển dựa theo chuẩn đó.

Một trong những tính năng nổi bật của ES6 đó là sự bổ sung letconst phục vụ cho việc khai báo biến dữ liệu. Vậy tại sao lại cần tới letconst dù trước đó đã có var để khai báo biến, thì ở bài viết này chúng ta sẽ cùng tìm hiểu lý do của từng kiểu khai báo biến.

2. Phân Biệt

2.1. Biến var

Như đã biết trong Vanilla Javascript, với từ khóa var chúng ta có thể khai báo đa dạng các kiểu biến như number, string, boolean, etc. Trừ trường hợp được khai báo bên trong 1 function (khi đó biến var sẽ có scope là function/locally scoped), biến var sẽ có scope là globally scoped. Đặc biệt, biến var còn có thêm tính chất hoisting: nghĩa là dù khai báo ở đâu thì biến đều sẽ được đem lên đầu scope trước khi code được thực hiện.

Lấy ví dụ:

    console.log (greeting);
    var greeting = "say hello";

sẽ được biên dịch là:

    var greeting;
    console.log(greeting); // greeting is undefined
    greeting = "say hello";

Nhưng có một vấn đề với biến var. Giả sử ta có ví dụ như sau:

    var greeting = "hey hi";
    var times = 4;

    if (times > 3) {
        var greeting = "say Hello instead"; 
    }

    console.log(greeting); //"say Hello instead"

Vì thỏa điều kiện if nên greeting khi này sẽ có giá trị là "say Hello instead" và sẽ vẫn giữ nguyên giá trị này sau khi thoát ra khỏi block if. Điều này sẽ không có gây vấn đề gì nhưng nếu trong trường hợp code của chúng ta lên đến hàng trăm, hàng nghìn dòng code, hoặc chúng ta cũng không biết được giá trị của biến liệu có bị thay đổi ở đoạn code nào sẽ dẫn đến việc debug là vô cùng khó khăn. Để giải quyết vấn đề trên thì ES6 cung cấp cho chúng ta thêm 2 cách khác để khai báo biến bao gồm letconst.

2.2. Biến let

Một trong những nguyên nhân khiến let có thể thay thế var để xử lý vấn đề nêu trên là vì biến let được khai báo sẽ có scope là block scoped chứ không phải globally hay locally scoped.

   let greeting = "say Hi";
   let times = 4;

   if (times > 3) {
        let hello = "say Hello instead";
        console.log(hello); // "say Hello instead"
    }
   console.log(hello); // hello is not defined

Chúng ta có thế thấy là đối với biến có scope là block scoped nếu ra khỏi scope được khai báo thì sẽ không thể sử dụng được nữa.

let cho phép chúng ta cập nhật giá trị của biến chứ không cho phép chúng ta tái khái báo lại biến đó.

    let greeting = "say Hi";
    console.log(greeting); //"say Hi"

    greeting = "say Hello instead";
    console.log(greeting); //"say Hello instead"

    -----------------------------------------------------

    let greeting = "say Hi";
    let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared

Tuy nhiên, đối với các block khác nhau thì việc tái khai báo biến sẽ không sinh ra lỗi vì đối với từng scope, mỗi biến sẽ được xem xét là 1 biến riêng khác biệt.

    let greeting = "say Hi";
    if (true) {
        let greeting = "say Hello instead";
        console.log(greeting); // "say Hello instead"
    }
    console.log(greeting); // "say Hi"

Giống với var, let cũng có tính hoisting tuy nhiên lại khác nhau ở chỗ thay vì var được khởi tạo với giá trị là undefined thì let sẽ không có bất kỳ giá trị khởi tạo nào. Điều này dẫn đến việc nếu chúng ta sử dụng biến let trước khi khai báo thì sẽ gặp lỗi Reference Error.

2.3. Biến const

Tương tự với let cũng có scope là block scoped, và hoisting thì chúng ta có thêm 1 kiểu khai báo biến nữa là const. Trong biến const nếu trường hợp kiểu của biến là primitive (bao gồm string, number, boolean, null, và undefined) thì chúng ta sẽ không thể tái khai báo hay cập nhật giá trị mới để thay thế cho giá trị trước đó của biến.

    const greeting = "say Hi";
    greeting = "say Hello instead"; // error : Assignment to constant variable. 

    ------------------------------------------------

    const greeting = "say Hi";
    const greeting = "say Hello instead"; // error : Identifier 'greeting' has already been declared

Đối với trường hợp kiểu biến là reference (bao gồm object, array, và function) thì tuy không thể tái khai báo hay cập nhật giá trị của biến nhưng chúng ta vẫn có thể cập nhật giá trị cho thuộc tính của biến đó.

    const greeting = {
        message : "Hello",
        number : "five"
    }

    greeting.message = "say Hello instead";
    console.log(greeting); // {message:"say Hello instead",number:"five"}

All rights reserved

Bình luận

Đăng nhập để bình luận
Avatar
@yendevy
thg 3 14, 2019 4:41 SA

vd chỗ này có gì đó sai sai bạn ha https://prnt.sc/mxm4oi

Avatar
@Creat10n
thg 3 14, 2019 6:00 SA

Thanks bạn nhé, mình vừa update lại rồi.

Avatar
@ducquoc
thg 2 8, 2020 7:18 SA
Avatar
@phongnm97
thg 2 26, 2020 8:04 SA

Bài viết thiếu đầu tư, dịch không để nguồn. 🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂ 🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂ 🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂ 🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂ 🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂🙅♂

Avatar
@khangnd
thg 11 6, 2020 6:04 SA

Bài dịch nên để nguồn để tôn trọng bản quyền của tác giả.

Avatar
@hamaianhnhi
thg 11 7, 2020 9:48 SA

chỗ này hình như có gì đó sai sai

2020-11-07_16-45-09.jpg

ví dụ:

let val;

console.log( val); // undefined

nhờ bạn giải thích chỗ này, theo như bài nói let dc khởi tạo ko có giá trị, thì khi sao in ra lại là undefined nhỉ?

Avatar
@Creat10n
thg 6 1, 2021 7:04 SA

Chỗ này mình đang nói về tính chất hoisting mà nên ví dụ bạn chưa ra như vậy là hông hợp lý rồi. Bạn phải đưa dòng console.log đó bỏ lên trước đoạn khai báo let val chứ.

Avatar
@phuonghuu71
thg 3 11, 2023 8:16 SA

Khúc này khai báo xong kh gán giá trị nó trả về undefined là đúng rồi ba 🤣🤣🤣, quê chưa 🤣🤣🤣

Avatar
@hsshp
thg 1 14, 2021 11:06 SA

cho em hỏi vs ạ,e có đoạn code sau thì khai báo var hay let (let showPassword hay var showPassword) đều giống nhau đúng k ạ let showPassword = false

btnElement.addEventListener('click', togglePassword)

function togglePassword() { if (showPassword) { showPassword = false } else { showPassword = true } }

Avatar
@truong0vanchien
thg 12 23, 2021 11:56 SA

Bai viet hay lam, cam on ban.

Avatar
@phantomkid2
thg 1 10, 2022 5:09 SA

Bài viết thiếu đầu tư, dịch không để nguồn 😃 không hiểu vì sao được nhiều upvote

Avatar
@RockerInNight
thg 2 20, 2023 10:47 SA

mục 2.3 có viết: "Trong biến const nếu trường hợp kiểu của biến là primitive (bao gồm string, number, boolean, null, và undefined) thì chúng ta sẽ không thể tái khai báo hay cập nhật giá trị mới để thay thế cho giá trị trước đó của biến." Biến được khai báo bằng let hoặc const thì đều không tái khai báo được khi trong cùng 1 scope, chứ không bắt buộc là dạng primitive.

Avatar
+109
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí