1. Kiến thức cần nắm
Trước tiên, để hiểu hết về var và let, chúng ta cần nhìn lại một số kiến thức về kiểu giá trị trong JS.
Kiểu nguyên thủy và tham trị
Trong Javascript, các kiểu nguyên thủy bao gồm:
String
Number
Boolean
và khi bạn khởi tạo một biến có kiểu giá trị là 1 trong 3 kiểu này, biến (có thể) được gọi là biến tham trị.
Tại sao lại vậy?
Vì khi bạn khai báo và gán giá trị, thứ mà biến này giữ là giá trị bạn đã khai báo. Không có gì khác! Khi bạn gán biến mới bằng một biến khác, nó chỉ lấy giá trị của biến mà bạn muốn gán, biến gốc này sẽ không có thay đổi hay ảnh hưởng gì khi bạn tác động lên biến mới.
Kiểu tham chiếu: object, array, function
Object, array, function là 3 kiểu tham chiếu trong Javascript, tức là, khi bạn khởi tạo 1 Object, V8 tạo ra một tham chiếu đến một vùng nhớ trên HEAP (vật lý là từ RAM) để lưu trữ giá trị. Mọi hành động của bạn tương tác với biến mà bạn lưu cái Object này là bạn tương tác với tham chiếu.
let user_01 = {
name: 'me',
age: 23
}
let user_02 = user_01
user_02.name='18 again'
user_01.age= 18
console.log(user_01)
console.log(user_02)
Đoán xem chuyện quái gì sẽ xảy ra?
Cả 2 đều là {name: '18 again', age: 18}!
Đúng rồi, vì chúng ta tạo 2 biến, nhưng gán biến 02 bằng biến 01, tức là tham chiếu biến 02 này đến vùng nhớ chứa giá trị của 01. Khi thay đổi 01 thì 02 sẽ thay đổi theo và ngược lại. Đó là lý do tại sao người ta gọi là tham chiếu.
Scope
Scope hiểu đơn giản là "vòng đời của một biến từ khi sinh ra đến khi biến mất".
Có 3 loại Scope: Block, Function, Global
Block thì có thể hiểu đơn giản là trong cặp ngoặc gần nhất mà biến được khai báo.
Funtion thì đơn giản là trong hàm.
Global tức là biến toàn cục, bạn định nghĩa ở đâu kệ bạn, đều dùng được ở tất cả mọi nơi.
OK, bây giờ bạn đã nắm được các kiến thức cần thiết. Chúng ta đi vào phần chính.
Sự khac biệt giữa let và var
let là block scope, var là function scope
function Test(){
if(1==1){
var v =100
let l = 200
}
console.log(v) //100
console.log(l) // not defined
}
Test()
Hoisting
Cả let và var đều được hoisting (kéo lên đầu khi chạy) nhưng sau đó thì lại khác nhau, biến khai báo bằng var được khai báo nhưng chưa gán giá trị, lúc này nó sẽ là undefined, còn let thì bạn không dùng được luôn.
console.log(a)
var a = 10 //undefine
console.log(b)
let b = 11 // b is not defined
Khi khai báo biến toàn cục, var sẽ gán nó thành thuộc tính của trình duyệt (window) luôn, còn let thì không.
var a = 10
console.log(window.a) //10
let b = 12
console.log(window.b) // undefined
Closure
Xét đoạn code này, kết quả sẽ là 3, 3, 3
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
Còn nếu thay thế var bằng let, kết quản lại là 0, 1, 2.
Tại sao lại vậy, vì mỗi vòng lặp với let, như đã nói ở trên, là block scope, nên EMCA sẽ tạo ra một block cho mỗi vòng lặp, ở đó sẽ định nghĩa một biến tạm lưu giá trị của i hiện tại:
{
let i = 0;
{
const iCopy = i;
setTimeout(() => console.log(iCopy), 1000);
}
i++;
{
const iCopy = i;
setTimeout(() => console.log(iCopy), 1000);
}
i++;
{
const iCopy = i;
setTimeout(() => console.log(iCopy), 1000);
}
}
còn với var, mọi thứ đơn giản hơn:
var i = 0;
setTimeout(() => console.log(i), 1000); // nhớ i (tham chiếu, không phải giá trị)
i++;
setTimeout(() => console.log(i), 1000); // vẫn nhớ biến i
i++;
setTimeout(() => console.log(i), 1000); // tiếp tục nhớ biến i
i++; // i = 3
Vì vòng lặp chạy xong rất nhanh, chỉ vài microsecond đã đếm i đến 3, mà đợi xong một giây (1000ms) mới log ra i (3 lần) nên kết quản sẽ đều là 3.
Const
Nói về const, nó không khác gì let ngoại trừ việc bạn không thể thay đổi nó, tuy nhiên vẫn có thể thay đổi thuộc tính của đối tượng được khai báo với const.
Hết. Xin cảm ơn các bạn đã theo dõi, thật ra mình đăng cái này để lúc nào đi phỏng vấn cần ôn tập một cách dễ dàng, không cần mở 10 tabs một lúc để đọc 11 cái blog, mong là không có đối thủ nào đọc được hehe.
Top comments (0)