Hoisting trong javascript
Bài đăng này đã không được cập nhật trong 5 năm
Javascript có một khái niệm khá kỳ quặc nhưng cũng rất quan trọng, đó chính là hoisting. Hôm nay mình sẽ giải thích cặn kẽ cho mọi người thế nào là hoisting và cách để chúng ta có thể tránh được những vẫn đề dễ gặp phải nếu không cẩn thận với nó.
Đầu tiên, mọi người hãy xem ví dụ sau đây:
function test(param) {
console.log(param);
}
test("hello world"); // hello world
Có lẽ mọi người có thể dễ dàng đoán được rằng function "test" sẽ in ra gì rồi . Tiếp theo các bạn hãy đoán xem kết quả mà function "test" sẽ in ra là gì trong ví dụ tiếp theo là gì nhé.
test("hello world"); // ?
function test(param) {
console.log(param);
}
Có lễ một số người, nhất là các bạn newbie sẽ ngạc nhiên khi biết rằng đoạn script trên vẫn sẽ in ra chữ "hello world" giống với ví dụ đầu tiên ! và đó chính là Hoisting.
Vậy Hoisting là gì ?
Hiểu một cách đơn giản thì javascript sẽ đưa việc "khởi tạo" các biến và function lên trên đầu function (scope) chứa các biến và function đó.
Bây giờ các bạn hãy nhìn lại vào ví dụ số 2, tuy ta gọi function test
đằng trước câu lệnh khởi tạo function test
. Tuy nhiên, javascript sẽ tự động đẩy câu lệnh khởi tạo test
lên trên cùng đoạn script, vậy nên đoạn lệnh test("hello world");
vẫn sẽ chạy như bình thường.
Vậy chúng ta đã cơ bản hiểu được các javascript xử lý việc khai báo các biến và function, bây giờ các bạn hãy thử đoán tiếp kết quả của đoạn script số 3 này nhé:
console.log(myName);
var myName = "huq"; // ?
Có lẽ không ít bạn sẽ nghĩ rằng đoạn script trên sẽ in ra "huq"
phải không . Thực ra kết quả sẽ là undefined
.
Như mình đã giải thích ở trên, javascript chỉ đẩy việc khởi tạo lên đầu, nhưng việc gán giá trị thì không đâu nhé . Chính vì vậy mà ví dụ số 3 sẽ in ra undefined
bởi vì biến myName
sẽ chỉ được gán cho giá trị "huq"
khi dấu =
xuất hiện đằng trược nó. Túm lại thì ví dụ số 3 có thể được viết như sau:
var myName; // khởi tạo myName
console.log(myName); // undefined (myName chưa có giá trị)
myName = "huq"; // gán myName cho giá trị"huq"
Có một lưu ý nhỏ mã các bạn cũng nên để ý đó là function
sẽ được đưa lên trên cả các biến nên mọi người hãy cẩn thận nhé .
Hoisting với let và const
Trước tiên, mình sẽ nói qua về let
và const
nhưng nếu các bạn chưa biết về es6 thì có thể bỏ qua phần này nhé. Cơ bản thì 2 từ khóa này cũng dùng để khởi tạo biến giống như var
nhé. Nhưng var
sẽ tạo property cho Global object (Window)
còn let
và const
thì không.
Cơ bản thì let
và const
vẫn sẽ được javascript hoist lên đầu function chứa chúng. Nhưng bạn sẽ gặp lỗi Cannot access '...' before initialization
nếu bạn khởi tạo một biến với const
mà không gán giá trị cho nó.
console.log(myAge);
const myAge = 20; // Uncaught ReferenceError: Cannot access 'myAge' before initialization
Tương tự:
const myAge;
console.log(myAge);
myAge = 20; // Uncaught SyntaxError: Missing initializer in const declaration
Hai Vậy nên, các bạn hãy nhớ gán giá trị cho các biến được khởi tạo bằng const
nhé !.
All rights reserved