Function Scopes

    var a = 2;
    console.log(a);
    foo();
    console.log(a + "aa");

    function foo() {
        a = 3;
        console.log(a + "bb");
        var a;
    }
    console.log(a + "cc");

E có đoạn code như trên khi chạy sẽ ra kết quả là :

 2

3bb 

2aa 

2cc

Nhưng nếu em comment var a trong function foo(); thì kết quả sẽ là :

2 
3bb 
3aa 
3cc

bác nào giải thích giúp e tại sao biến a trong function foo() lại thay biến a ban đầu?

1 Like

Bạn cần phải biết 2 khái niệm của JS

  1. là scope
  2. 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ề HoistingLexical Scope

9 Likes

dạ cảm ơn Bác. Bác giải thích rất chi tiết và dễ hiểu.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?