Bạn cần phải biết 2 khái niệm của JS
- là scope
- là hosting
Với scope khá đơn giản, scope là phạm vi mà 1 biến trong javascript tồn tại. Có 2 scope, 1 là global scope, 2 là local scope. Đễ dễ hiểu, không đi sâu xa thì biến được khai báo mà ko nằm trong cặp {} là global, còn nằm trong là local.
var a = 5;; // global
function c() { // << ngoặc
var b = 10; // local
} // << ngoặc
c();
console.log(a); // 5
console.log(b); // no, error :(
Tuy nhiên ở trong javascript, nếu bạn khai báo biến mà ko dùng từ khóa var, hoặc const hoặc let. Thì biến đó sẽ tự động được lôi ra global scope
function b() {
a = 10; // không dùng var nên a thành global
}
b(); // thực thi b, chứ ko nó ko chạy
console.log(a); // 10;
Với khái niệm thứ là hoisting, là một cơ chế của Javascript, giúp moi những khai báo của biến và hàm lên trên đầu scope hiện hành.
Vd:
a = 10;
var a;
Javascript sẽ hiểu thành
var a;
a = 10;
Từ 2 cái trên, ở vd 1 code bạn đã được áp dụng hoisting -> thành ntn
function foo() {
var a;
a = 3;
console.log(a + "bb");
}
Nên a thành local, và chỉ có phạm vi trong function foo() thôi.
Khi bạn bỏ var a ở trong foo() đi, a khi này ko bị hoisting nữa và nó thành global variable -> nó thay thế giá trị a ở ngoài cùng :3
Và kết quả là mọi thằng xài a đều chung số phận
Để tìm hiểu thêm, bạn có thể đọc về Hoisting và Lexical Scope