Vùng chết tạm thời và Nâng lên là hai thuật ngữ thiết yếu trong JavaScript. Nhưng hiểu cách chúng hoạt động có thể dễ dàng làm bạn bối rối nếu bạn không tiếp cận chúng đúng cách.
Nhưng đừng băn khoăn! Bài viết này ở đây để giúp bạn hiểu rõ về hai thuật ngữ.
Vì vậy, hãy thư giãn, thưởng thức tách cà phê yêu thích của bạn và bắt đầu với TDZ.
Chính xác thì Vùng chết tạm thời trong JavaScript là gì?
Một vùng chết tạm thời (TDZ) là khu vực của một khối mà một biến không thể truy cập được cho đến thời điểm máy tính hoàn toàn khởi tạo nó với một giá trị.
- Một khối là một cặp dấu ngoặc nhọn (
{...}
) dùng để nhóm nhiều câu lệnh. - Quá trình khởi tạo xảy ra khi bạn gán một giá trị ban đầu cho một biến.
Giả sử bạn cố gắng truy cập một biến trước khi khởi tạo hoàn chỉnh. Trong trường hợp như vậy, JavaScript sẽ ném một ReferenceError
.
Vì vậy, để ngăn JavaScript đưa ra lỗi như vậy, bạn phải nhớ truy cập các biến của mình từ bên ngoài vùng chết tạm thời.
Nhưng chính xác thì TDZ bắt đầu và kết thúc ở đâu? Hãy cùng tìm hiểu dưới đây.
Chính xác thì phạm vi của Vùng chết tạm thời nằm ở đâu?
Vùng chết tạm thời của một khối bắt đầu ở đầu phạm vi cục bộ của khối. Nó kết thúc khi máy tính khởi tạo đầy đủ biến của bạn với một giá trị.
Đây là một ví dụ:
{
// bestFood’s TDZ starts here (at the beginning of this block’s local scope)
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
console.log(bestFood); // returns ReferenceError because bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
let bestFood = "Vegetable Fried Rice"; // bestFood’s TDZ ends here
// bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
}
Hãy dùng thử trên StackBlitz
Trong đoạn mã trên, TDZ của khối bắt đầu từ dấu ngoặc nhọn mở ({
) và kết thúc khi máy tính khởi động bestFood
với giá trị chuỗi "Vegetable Fried Rice"
.
Khi bạn chạy đoạn trích, bạn sẽ thấy rằng console.log()
câu lệnh sẽ trả về một ReferenceError
.
JavaScript sẽ trả về một ReferenceError
bởi vì chúng tôi đã sử dụng console.log()
mã để truy cập bestFood
trước khi khởi tạo hoàn chỉnh. Nói cách khác, chúng tôi đã gọi bestFood
trong vùng chết tạm thời.
Tuy nhiên, đây là cách bạn có thể truy cập bestFood
thành công sau khi khởi tạo hoàn tất:
{
// TDZ starts here (at the beginning of this block’s local scope)
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
let bestFood = "Vegetable Fried Rice"; // bestFood’s TDZ ends here
console.log(bestFood); // returns "Vegetable Fried Rice" because bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
}
Hãy dùng thử trên StackBlitz
Bây giờ, hãy xem xét ví dụ này:
{
// TDZ starts here (at the beginning of this block’s local scope)
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
// bestFood’s TDZ continues here
let bestFood; // bestFood’s TDZ ends here
console.log(bestFood); // returns undefined because bestFood’s TDZ does not exist here
bestFood = "Vegetable Fried Rice"; // bestFood’s TDZ does not exist here
console.log(bestFood); // returns "Vegetable Fried Rice" because bestFood’s TDZ does not exist here
}
Hãy dùng thử trên StackBlitz
Bạn có thể thấy rằng điều đầu tiên console.log
mã trong đoạn mã trên được trả về undefined
.
JavaScript được trả về undefined
bởi vì chúng tôi đã không chỉ định bestFood
một giá trị trước khi sử dụng (gọi) nó. Như vậy, JavaScript đã mặc định giá trị của nó thành undefined
.
Hãy nhớ rằng bạn phải chỉ định một giá trị cho một const
biến trong khi khai báo nó. Ngoài ngoại lệ này, tất cả các nguyên tắc vùng chết tạm thời khác của let
biến cũng áp dụng cho const
. Tuy nhiên, var
hoạt động khác nhau.
TDZ của Var khác với các biến Let và Const như thế nào?
Sự khác biệt chính giữa vùng chết tạm thời của một var
, let
và const
biến là khi TDZ của họ kết thúc.
Chẳng hạn, hãy xem xét mã này:
{
// bestFood’s TDZ starts and ends here
console.log(bestFood); // returns undefined because bestFood’s TDZ does not exist here
var bestFood = "Vegetable Fried Rice"; // bestFood’s TDZ does not exist here
console.log(bestFood); // returns "Vegetable Fried Rice" because bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
// bestFood’s TDZ does not exist here
}
Hãy dùng thử trên StackBlitz
Khi bạn chạy đoạn mã trên, bạn sẽ thấy rằng cái đầu tiên console.log
tuyên bố sẽ trở lại undefined
.
Các console.log
câu lệnh đã trả về thành công một giá trị (undefined
) vì JavaScript tự động gán undefined
đến một cẩu var
Biến đổi.
Nói cách khác, khi máy tính kéo một var
biến, nó sẽ tự động khởi tạo biến với giá trị undefined
.
Ngược lại, JavaScript không khởi tạo một let
(hoặc const
) biến với bất kỳ giá trị nào bất cứ khi nào nó nâng biến đó lên. Thay vào đó, biến vẫn chết và không thể truy cập được.
Do đó, một let
(hoặc const
) TDZ của biến kết thúc khi JavaScript khởi tạo đầy đủ biến đó với giá trị được chỉ định trong quá trình khai báo.
Tuy nhiên, một var
TDZ của biến kết thúc ngay sau khi cẩu lên—không phải khi biến được khởi tạo đầy đủ với giá trị được chỉ định trong khi khai báo.
Nhưng chính xác thì “hoisting” nghĩa là gì? Hãy cùng tìm hiểu dưới đây.
Chính xác thì Hoisting có nghĩa là gì trong JavaScript?
cẩu đề cập đến việc JavaScript dành quyền ưu tiên cao hơn cho việc khai báo các biến, lớp và hàm trong quá trình thực thi chương trình.
Hoisting làm cho máy tính xử lý khai báo trước bất kỳ mã nào khác.
Ghi chú: Nâng lên không có nghĩa là JavaScript sắp xếp lại hoặc di chuyển mã lên trên mã khác.
Hoisting chỉ đơn giản là mang lại tính đặc hiệu cao hơn cho các khai báo JavaScript. Do đó, nó làm cho máy tính đọc và xử lý các khai báo trước khi phân tích bất kỳ mã nào khác trong chương trình.
Chẳng hạn, hãy xem xét đoạn trích này:
{
// Declare a variable:
let bestFood = "Fish and Chips";
// Declare another variable:
let myBestMeal = function () {
console.log(bestFood);
let bestFood = "Vegetable Fried Rice";
};
// Invoke myBestMeal function:
myBestMeal();
}
// The code above will return:
"Uncaught ReferenceError: Cannot access 'bestFood' before initialization"
Hãy dùng thử trên StackBlitz
Đoạn mã trên đã trả về một ReferenceError
do thứ tự ưu tiên mà máy tính thực hiện từng mã.
Nói cách khác, các khai báo của chương trình có quyền ưu tiên cao hơn so với các khởi tạo, yêu cầu và mã khác.
Hãy cùng xem qua từng bước về cách JavaScript thực thi đoạn mã trên.
Cách JavaScript cẩu hoạt động từng bước
Dưới đây là hướng dẫn về cách JavaScript thực thi đoạn mã trước đó.
1. JavaScript đã phân tích cú pháp đầu tiên bestFood
tuyên ngôn
let bestFood // This is the first bestFood declaration in the program
đầu tiên bestFood
khai báo biến là đoạn mã đầu tiên máy tính phân tích.
Lưu ý rằng sau khi máy tính đọc bestFood
khai báo biến, JavaScript sẽ tự động giữ biến trong một vùng chết tạm thời cho đến khi nó được khởi tạo hoàn toàn.
Do đó, mọi nỗ lực truy cập bestFood
trước khi khởi tạo hoàn chỉnh của nó sẽ trả về một ReferenceError
.
2. Máy tính đã phân tích cú pháp myBestMeal
sự định nghĩa biến
let myBestMeal
Các myBestMeal
khai báo biến là đoạn mã thứ hai mà JavaScript đã phân tích.
Ngay sau khi máy tính đọc myBestMeal
khai báo biến, JavaScript sẽ tự động giữ biến trong vùng chết tạm thời cho đến khi nó được khởi tạo hoàn toàn.
Do đó, mọi nỗ lực truy cập myBestMeal
trước khi khởi tạo hoàn chỉnh của nó sẽ trả về một ReferenceError
.
3. Máy tính khởi tạo bestFood
Biến đổi
bestFood = "Fish and Chips";
Bước thứ ba của máy tính là khởi tạo bestFood
với “Fish and Chips”
Chuỗi giá trị.
Do đó, việc triệu tập bestFood
tại thời điểm này sẽ trở lại “Fish and Chips”
.
4. JavaScript được khởi tạo myBestMeal
Biến đổi
myBestMeal = function() {
console.log(bestFood);
let bestFood = "Vegetable Fried Rice";
};
Thứ tư, JavaScript được khởi tạo myBestMeal
với chức năng được chỉ định. Vì vậy, nếu bạn đã gọi myBestMeal
tại thời điểm này, chức năng sẽ trở lại.
5. Máy tính được gọi myBestMeal
chức năng của
myBestMeal();
Lời kêu gọi của myBestMeal
chức năng của nó là hành động thứ năm của máy tính.
Sau khi gọi, máy tính xử lý từng mã trong khối chức năng. Tuy nhiên, các khai báo có quyền ưu tiên cao hơn các mã khác.
6. JavaScript đã phân tích cú pháp của hàm bestFood
tuyên ngôn
let bestFood // This is the second bestFood declaration in the program
Nhiệm vụ thứ sáu của JavaScript là phân tích chức năng của bestFood
sự định nghĩa biến.
Sau khi phân tích, JavaScript tự động giữ biến trong vùng chết tạm thời—cho đến khi quá trình khởi tạo hoàn tất.
Do đó, mọi nỗ lực truy cập bestFood
trước khi khởi tạo hoàn chỉnh của nó sẽ trả về một ReferenceError
.
7. Máy tính đã phân tích cú pháp của hàm console.log
bản tường trình
console.log(bestFood);
Cuối cùng, máy tính đọc console.log
tuyên bố—hướng dẫn hệ thống đăng nhập bestFood
nội dung của nó vào bảng điều khiển của trình duyệt.
Tuy nhiên, hãy nhớ rằng máy tính chưa khởi tạo đầy đủ chức năng của bestFood
biến chưa. Như vậy, biến hiện đang ở trong vùng chết tạm thời.
Do đó, nỗ lực truy cập biến của hệ thống đã trả về một ReferenceError
.
Ghi chú: Sau ReferenceError
trở lại, máy tính ngừng đọc mã của chức năng. Do đó, JavaScript đã không khởi tạo chức năng của bestFood
biến với "Vegetable Fried Rice"
.
gói nó lên
Hãy xem toàn bộ phần trước của chương trình của chúng tôi:
let bestFood // 1. JavaScript parsed the first bestFood declaration
let myBestMeal // 2. the computer parsed myBestMeal variable declaration
bestFood = "Fish and Chips"; // 3. the computer initialized the bestFood variable
myBestMeal = function () {
console.log(bestFood);
let bestFood = "Vegetable Fried Rice";
}; // 4. JavaScript initialized myBestMeal variable
myBestMeal(); // 5. the computer invoked myBestMeal’s function
let bestFood // 6. JavaScript parsed the function’s bestFood declaration
console.log(bestFood); // 7. the computer parsed the function’s console.log statement
Uncaught ReferenceError // bestFood’s invocation returned an Error
Bạn có thể thấy rằng JavaScript đã xử lý các khai báo của chương trình trước các mã khác.
Việc phân tích các khai báo trước mã khác trong một chương trình là cái mà chúng tôi gọi là “hoisting”.
Tổng quan
Bài viết này đã thảo luận về ý nghĩa của vùng chết tạm thời và cẩu trong JavaScript. Chúng tôi cũng đã sử dụng các ví dụ để minh họa cách cả hai hoạt động.
Cảm ơn vì đã đọc!
Và đây là một tài nguyên ReactJS hữu ích:
Tôi đã viết một cuốn sách về React!
- Nó thân thiện với người mới bắt đầu ✔
- Nó có các đoạn mã trực tiếp ✔
- Nó chứa các dự án có thể mở rộng ✔
- Nó có rất nhiều ví dụ dễ nắm bắt ✔
Cuốn sách Giải thích rõ ràng về React là tất cả những gì bạn cần để hiểu về ReactJS.