Hướng dẫn javascript hoisting - cẩu javascript

Là một vấn đề cản bước rất nhiều lập trình viên nắm giữ JavaScript. Hoistring là gì? Hoisting hoạt động như thế nào? Cùng theo dõi bài viết với mình nhé.Hoistring là gì? Hoisting hoạt động như thế nào? Cùng theo dõi bài viết với mình nhé.

Hướng dẫn javascript hoisting - cẩu javascript


1. Hoisting là gì?

Hôi à không hoisting là cơ chế của JavaScript cho phép các khai báo biến hoặc hàm được dời lên trên đầu phạm vi của chúng trước khi thực thi đoạn code.hoisting là cơ chế của JavaScript cho phép các khai báo biến hoặc hàm được dời lên trên đầu phạm vi của chúng trước khi thực thi đoạn code.

Điều này có nghĩa là bất kể hàm và biến được khai báo ở đâu, chúng đều được chuyển lên đầu phạm vi của chúng, bất kể là toàn cục hay cục bộ.

> Lưu ý: Là cơ chế này chỉ di chuyển phần khai báo mà thôi còn các phần khác giữ nguyên không đụng gì đến nó hết.Lưu ý: Là cơ chế này chỉ di chuyển phần khai báo mà thôi còn các phần khác giữ nguyên không đụng gì đến nó hết.

1.1. Hành vi hoisting đối với biến

Trong JavaScript, ta có thể sử dụng biến trước khi khai báo nó, như thế này:

// Gán cho chuỗi NIIT cho biến thuongHieu

thuongHieu = "NIIT"; = "NIIT";

// Sử dụng biến thuongHieu

console.log(thuongHieu); .log(thuongHieu);

// Khai báo thuongHieu

var thuongHieu;   thuongHieu;
 

Kết quả:

Và JavaScript chỉ lưu trữ các khai báo, không lưu trữ các khởi tạo:

// Khai báo và khởi tạo biến thuongHieu

var thuongHieu = "NIIT"; thuongHieu = "NIIT";

// In ra thông tin biến

console.log(thuongHieu + " thành lập năm: " + namThanhLap);.log(thuongHieu + " thành lập năm: " + namThanhLap);

// Khai báo và khởi tạo biến namThanhlap

var namThanhLap = 2002;   namThanhLap = 2002;
 

Nếu như bạn nghĩ kết quả nhận được: NIIT thành lập năm: 2002 thì xin lỗi...

Kết quả nhận được như thế này cơ:

NIIT thành lập năm: undefined  
 

Bởi vì, ngay khi chạy chương trình thì JavaScript sẽ thực hiện khai báo một lượt các biến chưa sử dụng là lưu trữ nó.

Tuy nhiên, các biến này dù có được bạn khởi tạo thì JavaScript trước tiên vẫn gán cho nó giá trị mặc định là undefined.

Để hiểu hoạt động của hoisting đối với biến thì hãy cùng tìm hiểu tiếp ví dụ:

console.log(message);.log(message);

var message = "Lập trình JavaScript căn bản";  message = "Lập trình JavaScript căn bản";

}

hoi();  ();
 

Kết quả ta được:

Tại sao hồi nãy nói là hoisting sẽ chuyển phần khai báo lên trên đầu phạm vi khi thực thi mà nó lại ra kết quả undefined?hoisting sẽ chuyển phần khai báo lên trên đầu phạm vi khi thực thi mà nó lại ra kết quả undefined?

Thực ra thì nó chuyển phần khai báo như này nè:

var message; message;

console.log(message);.log(message);

message = "Lập trình JavaScript căn bản";  = "Lập trình JavaScript căn bản";

}  
 

Như bạn đã biết, khi khai báo biến mà không gán dữ liệu thì mặc định nó có giá trị là undefied

Như vậy thì khi thực thi chương trình:

  • Phần khai báo sẽ được chuyển lên đầu hàm hoi()
  • Nhưng phần gán giá trị sẽ không được chuyển nên khi in ra sẽ là in ra undefined.

Các bạn lưu ý phần này nhé.

Để tránh những trường hợp như vậy xuất hiện về sau thì bạn nên khai báo và khởi tạo cùng một lúc như sau:

// Vừa khai báo, vừa khởi tạo

// trước khi sử dụng

var message = "Lập trình JavaScript căn bản"; message = "Lập trình JavaScript căn bản";

console.log(message);.log(message);

}

hoi();  ();
 


Kết quả ta được:

Tại sao hồi nãy nói là hoisting sẽ chuyển phần khai báo lên trên đầu phạm vi khi thực thi mà nó lại ra kết quả undefined?khai báo hàm (function declarations) và biểu thức hàm (function expression).

Thực ra thì nó chuyển phần khai báo như này nè:Hàm trong JavaScript ngay

message = "Lập trình JavaScript căn bản";

}  

Như bạn đã biết, khi khai báo biến mà không gán dữ liệu thì mặc định nó có giá trị là undefied

Như vậy thì khi thực thi chương trình:

hoi();();

Phần khai báo sẽ được chuyển lên đầu hàm hoi()

function hoi() { hoi() {

var message = "Lập trình JavaScript căn bản"; message = "Lập trình JavaScript căn bản";

1.2. Hành vi hoisting đối với hàm.write(message);

}  
 

Như bạn đã biết, khi khai báo biến mà không gán dữ liệu thì mặc định nó có giá trị là undefied

function hoi() { hoi() {

var message = "Lập trình JavaScript căn bản"; message = "Lập trình JavaScript căn bản";

document.write(message);.write(message);

}  
 

Như bạn đã biết, khi khai báo biến mà không gán dữ liệu thì mặc định nó có giá trị là undefied

hoi();  ();
 

Kết quả ta được:

Tại sao hồi nãy nói là hoisting sẽ chuyển phần khai báo lên trên đầu phạm vi khi thực thi mà nó lại ra kết quả undefined?cơ chế hoisting.

Thực ra thì nó chuyển phần khai báo như này nè:

message = "Lập trình JavaScript căn bản";

}  

Như bạn đã biết, khi khai báo biến mà không gán dữ liệu thì mặc định nó có giá trị là undefied

Như vậy thì khi thực thi chương trình:

Phần khai báo sẽ được chuyển lên đầu hàm hoi()();

Nhưng phần gán giá trị sẽ không được chuyển nên khi in ra sẽ là in ra undefined.

var hoi = function() { hoi = function() {

var message = "Lập trình JavaScript căn bản"; message = "Lập trình JavaScript căn bản";

document.write(message);.write(message);

1.2. Hành vi hoisting đối với hàm
 

Đối với hàm thì chúng ta biết là trong JavaScript có hai dạng hàm đó là khai báo hàm (function declarations) và biểu thức hàm (function expression).

> Quên thì xem lại bài Hàm trong JavaScript ngay
 

+ Đối với Khai báo hàm:

hois();();

hoi();  ();
 

// Biểu thức hàm

var hois = function hoi() { hois = function hoi() {

var message = "Lập trình JavaScript căn bản"; message = "Lập trình JavaScript căn bản";

document.write(message);.write(message);

};  
 


2. So sánh thứ tự ưu tiên trong cơ chế hoisting


2.1. Gán biến ưu tiên hơn khai báo hàm

Trong cơ chế hoisting, phép gán biến nó sẽ có độ ưu tiên cao hơn khai báo hàm:

<html>

<body>

<script>

// Khai báo và khởi tạo biến message

var message = "Đây là biến chuỗi"; message = "Đây là biến chuỗi";

// Khai báo hàm message (trùng tên)

function message() { message() {

document.write("Đây là hàm");.write("Đây là hàm");

}  
 

//in ra kiểu của message

document.write(typeof message);.write(typeof message);

script>

body>

// Khai báo và khởi tạo biến messagehtml>
 

var message = "Đây là biến chuỗi";string.

// Khai báo hàm message (trùng tên)Khai báo hàm đã không thành công.

document.write("Đây là hàm");

}  

//in ra kiểu của message

<html>

<body>

<script>

// Khai báo và khởi tạo biến message

var message = "Đây là biến chuỗi"; message = "Đây là biến";

// Khai báo hàm message (trùng tên)

var message = function() { message = function() {

document.write("Đây là hàm");.write("Đây là hàm");

}  

//in ra kiểu của message

document.write(typeof message);.write(typeof message);

script>

body>

// Khai báo và khởi tạo biến messagehtml>
 

var message = "Đây là biến chuỗi";string.

// Khai báo hàm message (trùng tên)

document.write("Đây là hàm");function

}  

//in ra kiểu của messagekhai báo hàm có độ ưu tiên cao hơn khai báo biến, ví dụ:

DOCTYPE html>

<html>

<body>

<script>

// Khai báo và khởi tạo biến message

var message = "Đây là biến chuỗi"; message;
 

// Khai báo hàm message (trùng tên)

document.write("Đây là hàm"); message() {

document.write("Đây là hàm");.write("Đây là hàm");

}  
 

//in ra kiểu của message

document.write(typeof message);.write(typeof message);

script>

body>

// Khai báo và khởi tạo biến messagehtml>
 

var message = "Đây là biến chuỗi";function, chứng tỏ khai báo hàm ưu tiên hơn là khai báo biến.

// Khai báo hàm message (trùng tên)

document.write("Đây là hàm");

}  

//in ra kiểu của message

  •  
  • Khi chạy trên trình duyệt, ta sẽ được kết quả là string.

Điều này chứng to việc cố gắng ghi đè biến message bằng Khai báo hàm đã không thành công.Strict Mode trong JavaScript

2.2. Biểu thức hàm ưu tiên hơn gán biến

Ta cố tính khai báo và khởi tạo một biến message.không cho phép sử dụng cho đến khi được khai báo.

Sau đó lại tạo ra một biểu thức hàm có tên là message.

// Khai báo biến

console.log(thuongHieu);.log(thuongHieu);

var message = "Đây là biến";

// Khai báo hàm thuongHieu;
 

}

Trong trường hợp Khai báo hàm thì kết quả là string.
 

Còn khi là Biểu thức hàm như ví dụ này thì sao?

Khi chạy trên trình duyệt ta có kết quả: function

2.3. Khai báo hàm ưu tiên hơn khai báo biến

Trong cơ chế hoisting, nó phép khai báo hàm có độ ưu tiên cao hơn khai báo biến, ví dụ:Ghi chú: Vấn đề này sẽ không gặp phải đối với một ngôn ngữ chặt chẽ như JAVA. Bởi vì ngay từ đầu JAVA đã được thiết kế để dành cho những dự án lớn, thiết kế tốt cho việc duy trì, mở rộng dự án trong tương lai. HỌC JAVA ngay nếu bạn thích những thứ gì chặt chẽ, quy củ.

var message;  

function message() { hoisting trong JavaScript. Đây là một vấn đề rất quan trọng, hiểu và nắm giữ nó thì bạn mới biết thực sự JavaScript hoạt động như thế nào.

Kết quả sẽ in ra là function, chứng tỏ khai báo hàm ưu tiên hơn là khai báo biến.nắm bắt hoisting trong JS cũng khá khó. Nhưng hãy luyện tập, THỬ - SAI để ngộ ra dần dần bạn nhé.

3. Đối phó với vấn đề hoisting như thế nào?