PHẦN CƠ BẢN
VÒNG LẶP
DATA TYPES
EVENTS
DOM
BOM
OBJECT
BỔ SUNG
THỰC HÀNH
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Cơ chế hoạt động của hoisting trong Javascript

Trong bài này chúng ta sẽ tìm hiểu hoisting trong Javascript, qua đó sẽ giúp bạn hiểu khái niệm hosting là gì, và cơ chế hoạt động của hosting trong ngôn ngữ javascript.

Hoisting là vấn đề liên quan đến cách khai báo biến trong Javascript. Theo quy tắc chung của hầu hết các ngôn ngữ lập trình, để sử dụng một biến thì bạn phải khai báo nó trước. Nhưng javascript thì lại khác, có một số trường hợp bạn có thể sử dụng biến rồi mới khai báo sau. Lý do là gì thì chúng ta cùng tìm hiểu ngay nhé.

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

1. Hoisting trong javascript là gì?

Khi bạn thực thi một đoạn mã javascript thì trình biên dịch sẽ tạo ra một bối cảnh thực thi chung, ta gọi là global execution context.

Bối cảnh thực thi này sẽ có hai giai đoạn, thứ nhất là tạo và thứ hai là thực thi.

Trong giai đoạn tạo thì javascript sẽ di chuyển các khai báo biến lên đầu của đoạn mã, giúp cho chương trình không bị lỗi khi sử dụng biến trước khi khai báo. Tính năng này ta gọi là tính năng lưu trữ trong javascript, và trong tiếng Anh gọi là Hoisting.

2. Biến hoisting trong javascript

Trong Javascript, bạn có thể định nghĩa một biến sau khi sử dụng nhờ tính năng hoisting.

Javascript sẽ di chuyển toàn bộ các khai báo biến lên đầu chương trình. Vì vậy, những dòng code có sử dụng biến mà chưa khai báo sẽ không bị lỗi.

// Gán nhưng chưa khai báo biến
domain = 'freetuts.net';

// Kết quả: Domain là freetuts.net
document.write("Domain là: " + domain);

// Khai báo
var domain;

// Kết quả: Domain là freetuts.net
document.write("<br/> Domain là: " + domain);

Nếu trong lúc khởi tạo mà bạn gán giá trị cho biến thì kết quả sẽ khác

// Gán nhưng chưa khai báo biến
domain = 'freetuts.net';

// Kêt quả: Domain là freetuts.net
document.write("Domain là: " + domain);

// Khai báo
var domain = 'techtuts.net';

// kêt quả: Domain là freetuts.net
document.write("<br/> Domain là: " + domain);

Nếu khai báo biến trước khi sử dụng thì ta vẫn có kết quả giống nhau.

// Khai báo
var domain;

// Gán nhưng chưa khai báo biến
domain = 'freetuts.net';

// Kết quả: Domain là freetuts.net
document.write("Domain là: " + domain);

// Kết quả: Domain là freetuts.net
document.write("<br/> Domain là: " + domain);

Trong ví dụ thứ 3 này thì ta đã khai báo biến trước rồi mới sử dụng sau. Điều này tuân thủ theo quy tắc tạo biến rồi mới sử dụng của hầu hết các ngôn ngữ lập trình. Nó giúp chương trình trở nên sáng và logic hơn.

3. Từ khóa let và var trong hoisting

Việc sử dung từ khóa let var để khai báo một biến sẽ có sự khác biệt trong hoisting.

Sử dụng var: Nếu biến chưa gán giá trị thì sẽ trả về undefined.

console.log(counter); // undefined
var counter = 1;

Đoạn mã trên sẽ tương đương với đoạn mã dưới đây.

var counter;

console.log(counter); // undefined
counter = 1;

Sử dụng let: Nếu biến chưa gán giá trị thì sẽ xuất hiện thông báo lỗi Cannot access before initialization.

console.log(counter);
let counter = 1;

Kết quả:

"ReferenceError: Cannot access 'counter' before initialization

Lỗi này muốn nói rằng biến counter đã được định nghĩa trong bộ nhớ heap nhưng chưa được khởi tạo.

4. Hàm hoisting trong javascript

Cũng giống như các biến, công cụ JavaScript cũng lưu trữ các khai báo hàm. Nó sẽ di chuyển các khai báo hàm lên đầu của chương trình.

let x = 20,
    y = 10;

let result = add(x,y);
console.log(result);

function add(a, b){
    return a + b;
}

Trong ví dụ này thì mình đã sử dụng hàm add rồi mới khai báo sau. Tuy nhiên, javascript vẫn không trả về một lỗi nào cả. Lý do là cơ chế hoisting của javascript đã di chuyển các khai báo hàm lên đầu rồi mới thực thi chương trình.

Có nghĩa là đoạn code dưới đây sẽ tương đương:

function add(a, b){
    return a + b;
}

let x = 20,
    y = 10;

let result = add(x,y);
console.log(result);

5. Hoisting trong biểu thức hàm

Biểu thức hàm hay còn gọi là function expressions. Nó là một hàm được khai báo bằng cách gán vào một biến.

var add = function(x, y) {
    return x + y;
}

Hàm add chính là một function expressions.

Quay trở lại bài toán. Câu hỏi là chuyện gì sẽ xảy ra nếu ta sử dụng một function expressions trước rồi mới khai báo sau? Hãy xem ví dụ dưới đây.

let x = 20,
    y = 10;

let result = add(x,y);
console.log(result);

var add = function(x, y) {
    return x + y;
}

Chạy đoạn code này thì kết quả sẽ xuất hiện lỗi:

"TypeError: add is not a function

Lý do rất đơn giản. Javascript sẽ xem biết add là một biến thông thường, nên khi nó đưa lên đầu thì sẽ là một biến chứ không phải là một hàm. Vì vậy, khi sử dụng sẽ xuất hiện lỗi add is not a function.

6. Hoisting trong arrow function

Cú pháp tạo arrow function sẽ như sau:

var function_name = () => bieuthuc;

Chính vì vậy, nếu bạn sử dụng arrow function trước rồi mới khai báo thì sẽ bị lỗi function_name không phải là một hàm.

7. Lời kết

Hoisting nghe có vẻ kì lạ và hay, nhưng riêng cá nhân mình thấy hoisting không thực sự tốt. Bởi theo sự logic của các ngôn ngữ lập trình là bạn phải sử dụng một biến trước khi khai báo chúng. Và Hoisting trong javascript đã phá vỡ đi quy tắc đó.

Cùng chuyên mục:

Cách gộp hai object javascript lại với nhau

Cách gộp hai object javascript lại với nhau

Cách lấy chiều dài của object trong Javascript

Cách lấy chiều dài của object trong Javascript

Hướng dẫn giải phương trình bậc 1 bằng Javascript

Hướng dẫn giải phương trình bậc 1 bằng Javascript

Cách dùng nextSibling trong javascript

Cách dùng nextSibling trong javascript

Cách dùng insertAdjacentHTML trong javascript

Cách dùng insertAdjacentHTML trong javascript

Cách dùng innerHTML trong Javascript

Cách dùng innerHTML trong Javascript

Cách dùng insertBefore trong javascript

Cách dùng insertBefore trong javascript

Cách dùng insertAfter trong Javascript

Cách dùng insertAfter trong Javascript

Cách dùng parentNode trong Javascript

Cách dùng parentNode trong Javascript

Cách dùng parentElement trong Javascript

Cách dùng parentElement trong Javascript

Tính tổng các phần tử trong mảng javascript

Tính tổng các phần tử trong mảng javascript

Tính tổng hai số bằng Javascript (cộng hai số)

Tính tổng hai số bằng Javascript (cộng hai số)

Cách gán giá trị cho thẻ input trong javascript

Cách gán giá trị cho thẻ input trong javascript

Để gán giá trị cho thẻ input thì ta có hai cách, thứ nhất là…

Cách kiểm tra số nguyên âm trong javascript

Cách kiểm tra số nguyên âm trong javascript

Cách kiểm tra số nguyên dương trong javascript

Cách kiểm tra số nguyên dương trong javascript

Hàm closure trong javascript

Hàm closure trong javascript

Closure là một khái niệm không phải ai cũng ..

Biểu thức chính quy RegEx trong Javascript

Biểu thức chính quy RegEx trong Javascript

Bài này chúng ta sẽ tìm hiểu đến chuỗi và cách sử dụng biểu thức…

Cách dùng Import / Export Module trong javascript

Cách dùng Import / Export Module trong javascript

Khi bạn xây dựng một ứng dụng nhỏ thì việc đặt

Cấp độ private / protected của class trong Javascript

Cấp độ private / protected của class trong Javascript

Cách dùng static trong Javascript (thuộc tính và phương thức tĩnh)

Cách dùng static trong Javascript (thuộc tính và phương thức tĩnh)

Trong bài này chúng ta sẽ tìm hiểu cách sử dụng từ ..

Top