ES6 block bindings (variables)
Bài đăng này đã không được cập nhật trong 8 năm
Nếu các bạn đã từng lập trình C/C++ chắc các bạn đã quen với việc các biến (variables hay bindings) được tạo ra và có phạm vi sử dụng trong đúng khối lệnh (block). Nhưng trong Javascript thì khác, với phiên bản ES6 (ECMAScript 6) các biến được khởi tạo và phạm vi hoạt động sẽ phụ thuộc vào cách mà bạn khai báo nó với từ khóa var
hay let
. Với từ khóa mới let
trong ES6 sẽ giúp bạn thao tác scope và block một cách dễ dàng và an toàn hơn.
1. Khai báo biến với từ khóa var
(Declarations are Hoisted)
Trong Javscript khai báo biến với từ khóa var
bạn có thể sử dụng biến trước khi khai báo nó mà không gặp bất cứ lỗi hay cảnh báo (warning) nào cả. Chắc các bạn cũng thắc mắc tại sao lại vậy? Để hiểu được điều này ta cần phải tìm hiểu một từ khóa trong Javascript là 'hoisting'. Hoisting là một hành động mặc định của JavaScript luôn đưa khai báo biến với từ khóa var
lên trên đầu của scope hiện tại và bạn có khai báo bao nhiêu lần thì nó cũng tương đương với một lần duy nhất ở trên đầu scope. Để hiểu thêm ta sẽ xét vài ví dụ sau đây:
function test() {
x = 5; // Assign 5 to x
console.log(x);
var x; // Initialize x
console.log(x);
}
test(); // => 5\n5
Trong ví dụ trên ta có thể thấy mặc dù biễn x được gán giá trị bằng 5 trước khi khai báo nó. Đoạn code này vẫn chạy bình thường và in ra x trong 2 lần với giá trị như nhau là 5.
Như vậy đoạn code trên hoàn toàn tương đương với đoạn code sau
function test() {
var x; // Initialize x
x = 5; // Assign 5 to x
console.log(x);
console.log(x);
}
test(); // => 5\n 5
Ta xét một ví dụ khác
function test() {
var x = 5; // Initialize x
console.log(x);
console.log(y)
var y = 7; // Initialize y
}
test() // => 5\n undefined
Nhìn vào ví dụ trên hẳn có bạn sẽ nghĩ ràng sẽ in ra 2 giá trị là 5 và 7 tương ứng với x và y. Tuy nhiên bạn cần hiểu rõ Javascript hoisting chỉ đưa khai báo lên trên đầu scope chứ không bao gồm cả phần khởi tạo. Như vậy đoạn code trên sẽ tương ứng với đoạn code sau
function test() {
var x;
var y;
x = 5; // Initialize x
console.log(x);
console.log(y)
y = 7; // Initialize y
}
test() // => 5\n undefined
Phạm vi của biến (scope) khi khai báo với từ khóa var
trong javascript có khác so với C/C++ nó không phải gói gọn trong khối lệnh (block), mà phạm vi của nó là function. Nghĩa là bạn khai báo biến ở bất cứ đâu trong block thì ở phần thân function chứ block đó đều dùng được.
function test(condition) {
if (condition) {
var result = "blue";
} else {
// can access result here with value is undefined
}
console.log(result);
}
test(true) // => blue
test(false) // => undefined
Như bạn có thể thấy mặc dù biến test được khai báo khi mà parameter condition
có giá trị là true
nhưng nó vẫn có thể được truy cập ở bên ngoài khối lệnh này. Như vậy đoạn code trên hoàn toàn tương đương với
function test(condition) {
var result;
if (condition) {
result = "blue";
} else {
// can access result here with value is undefined
}
console.log(result);
}
test(true) // => blue
test(false) // => undefined
Với đoạn code này bạn hoàn toàn có thể hiểu được ngay Javascript không báo lỗi là chưa định nghĩa biến result
.
Vậy khai báo biến với từ khóa let
trong ES6 có gì khác biệt. Chúng ta cùng tìm hiểu ngay sau đây
2. Khai báo với từ khóa let
Về cơ bản thì cú pháp let
khá giống với var
. Có một điểm khác biệt lớn nhất là khai báo biến với let
không hoisted, có nghĩa là phạm vi của biến chỉ trong block mà nó được khai báo và phải khai báo trước khi sử dụng. Để hiểu rõ hơn ta có ví dụ sau
function test(condition) {
if (condition) {
let result = "blue";
console.log(result);
} else {
// can't access result here
console.log(result); // will raise errors
}
// can't access result here
}
test(true) // => blue
test(false) // => will raise errors
Qua ví dụ trên ta thấy việc khai báo biến với từ khóa let
thì phạm vi hoạt động của biến giống với C/C++, phạm vi của nó là block lệnh chứ không phải là scope như var
. Cũng tương tự khi khai báo biến trong vòng lặp ....
for(let i = 0; i < 10; i++) {
console.log(i);
}
// // can't access i here
Khác với var
bạn có thể khai báo biến trùng tên bao nhiêu lần tùy thích. Khi sử dụng let
là bạn không thể khai báo biến 2 lần với cùng một tên. Nếu bạn khai báo 2 biến trùng một tên sẽ raise ra lỗi. Ta cùng xem một vài ví dụ cho trường hợp này
function test() {
var a = 1;
let a = 1; // raise error here
}
function test() {
let a = 1;
let a = 1; // raise error here
}
function test() {
let a = 1; // raise error here
var a = 2;
}
Qua các ví dụ trên, ta thấy việc khai báo biến với từ khóa let
các biến có phạm vi hoạt động rõ ràng do không sử dụng cơ chế hoisting. Hơn nữa với let
ta cần tuân thủ nguyên tắc cần khai báo biến trước khi sử dụng và chỉ được khai báo duy nhất một lần cho một biến trong cùng block như vậy sẽ an toàn hơn rất nhiều.Vì vậy nếu bạn dùng ES6 thì cũng được khuyến cáo là nên dùng let
thay thế cho var
như vậy code của bạn sẽ chạy một cách sáng sủa và an toàn hơn rất nhiều.
Hi vọng qua bài viết bạn sẽ hiểu thêm về 2 cách khai báo biết với let
và var
trong ES6. Cảm ơn đã theo dõi bài viết!
All rights reserved