Rất nhiều tính năng mới được ra mắt với ES2015 (ES6). Một trong những tính năng nổi bật của ES6 đó là sự bổ sung let
và const
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 let
và const
dù trước đó đã có var
để khai báo biến, bài viết này sẽ giúp chúng ta tìm hiểu lý do, phạm vi, cách sử dụng và lưu trữ của từng kiểu khai báo biến.
function/locally scoped hoặc globally scoped (phạm vi cục bộ hoặc phạm vi toàn cục). Phạm vi là toàn cục khi một biến kiểu var được khai báo bên ngoài một function (hàm). Điều này có nghĩa, bất kỳ biến nào được khai báo bên ngoài một function (hàm) hay một khối đều có thể được truy cập ở mọi nơi trong chương trình. Ngoài ra, biến var
còn có thêm tính chất hoisting: 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.
Để hiểu thêm, hãy xem ví dụ dưới đây.
var name = "John";function newFunction() {var fullName = "John Jane"}
Ở đây, name
là biến có phạm vi toàn cục vì nó tồn tại bên ngoài hàm (hay 1 khối) trong khi fullName
là biến có phạm vi chức năng. Vì vậy, không thể truy cập đến biến fullName
ở bên ngoài hàm.
Điều này có nghĩa là chúng ta có thể thực hiện việc này trong cùng một phạm vi và sẽ không gặp lỗi.
var name = "John Doe";var name = "John Jane";
nhận được kết quả tương tự như khi thực hiện
var name = "John Doe";name = "John Jane";
var
Giả sử ta có ví dụ sau:
var name = "John Doe";var someBool = true;if (someBool) {var name = "Daniel Joan";}console.log(name);
Vì thỏa điều kiện if
nên name lúc này sẽ có giá trị là “Daniel Joan” 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ó vấn đề gì trong trường hợp chương trình code ngắn, đơn giản và chúng ta biết rõ giá trị của biến bị ghi đè ở đoạn code nào. Nhưng ở trường hợp ngược lại, 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 let
và const
.
let
là phiên bản cải tiến của từ khóa var
. Nó cũng giải quyết vấn đề var
mà chúng ta vừa đề cập ở trên.
block scoped (phạm vi khối). Phạm vi của một biến let
chỉ là phạm vi khối. Nó không thể truy cập được bên ngoài một khối cụ thể ({block}). Khối là một đoạn mã được giới hạn bởi dấu {}. Vì vậy, một biến kiểu let
được khai báo trong một khối chỉ có thể được truy cập và sử dụng trong khối đó.
let someBool = true;let name = "john";if(someBool){let firstName = "Jane";console.log(firstName); // Jane}console.log(firstName); // firstName is not defined
Chúng ta thấy rằng việc sử dụng firstName
bên ngoài khối của nó (ngoài dấu {}) trả về một lỗi. Nhận được kết quả này là do let
chỉ có phạm vi khối.
let
cho phép cập nhật giá trị nhưng không được khai báo lạiGiống như var
, một biến được khai báo với từ khóa let
có thể được cập nhật lại, nhưng biến đó không được phép khai báo lại trong phạm vi của nó. Vì vậy, trong khi điều này sẽ hoạt động:
let firstName = "John";firstName = "jane";
việc thực hiện câu lệnh dưới đây sẽ trả về một lỗi:
let firstName = "John";let firstName = "Jane"; // error: Identifier 'firstName' has already been declared
Tuy nhiên, nếu cùng một tên biến nhưng được khai báo trong các phạm vi khác nhau, sẽ không có lỗi do hai biến là khác nhau vì chúng có phạm vi khối khác nhau
let firstName = "John";if (true) {let firstName = "Jane";console.log(firstName); // "Jane"}console.log(firstName); // "John"
Điều này làm cho let
trở thành sự lựa chọn tốt hơn var
. Khi sử dụng let
, chúng ta không cần phải bận tâm nếu trước đó đã sử dụng tên cho một biến vì một biến chỉ tồn tại trong phạm vi của nó.\
Từ khóa const
có tất cả các thuộc tính giống như từ khóa let
, ngoại trừ việc người dùng không thể gán lại giá trị cho nó.
block scoped (phạm vi khối), tương tự như let
, const
chỉ có thể được truy cập và sử dụng trong khối mà chúng đã được khai báo. Khi chúng ta khai báo một biến const
, cần khởi tạo giá trị ban đầu cho nó, nếu không, nó sẽ trả về một lỗi.
const
không thể được cập nhật hoặc khai báo lạiĐiều này có nghĩa, giá trị của một biến được khai báo kiểu const
vẫn giữ nguyên trong phạm vi của nó. Nó không thể được gán lại giá trị hoặc khai báo lại. Vì vậy, nếu chúng ta khai báo một biến với từ khóa const
, chúng ta không thực hiện đoạn code sau:
const firstName = "John";firstName = "jane"; // error: Assignment to constant variable
const firstName = "John";const firstName = "Jane"; // error: Identifier 'firstName' has already been declared
Tuy không thể thay đổi được thuộc tính hay giá trị của biến , nhưng chúng ta có thể thay đổi giá trị thuộc tính của biến const
đó. Ví dụ ta có 1 object như sau:
const name = {firstName: "John",lastName: "Jane"}// It is allowedname.firstName = "Selena"// It is not allowedname = {b: 10,prop2: 9}
var
có phạm vi toàn cục hoặc phạm vi cục bộ trong khi let
và const
chỉ có phạm vi khối.var
có thể được cập nhật và khai báo lại trong phạm vi của nó; Các biến khai báo theo từ khóa let
có thể được cập nhật nhưng không được khai báo lại; Các biến khai báo theo từ khóa const
không thể được cập nhật hoặc khai báo lại.var
được khởi tạo bằng undefined, các biến kiểu let
và const
không được khởi tạo.var
và let
có thể được khai báo mà không cần khởi tạo, const
phải được khởi tạo trong quá trình khai báo.let
được ưu tiên hơn const
khi giá trị mà nó trỏ tới sẽ thay đổi theo thời gian.const
thường được sử dụng cho các giá trị toàn cầu, không đổi.const
.