Khi bạn xác định một biến với var
, khai báo biến được "hoisted" lên đầu phạm vi và do đó biến được xác định cho toàn bộ phạm vi. Việc khởi tạo biến (gán giá trị ban đầu của nó) vẫn ở cùng một vị trí trong mã.
Vì vậy, trong ví dụ thứ hai của bạn, khi bạn thực hiện alert(box)
, biến số box
đã được khai báo do tuyên bố hoán đổi var
. Ví dụ thứ hai của bạn:
alert(box);
var box = "Thinking outside the box";
về cơ bản là tương đương với này (khai báo của biến box
được kéo lên đến đỉnh của phạm vi):
var box;
alert(box);
box = "Thinking outside the box";
Điều này làm cho biến box
tuyên bố (mặc dù không được khởi tạo) trước câu lệnh alert(box)
của bạn và do đó bạn nhận được kết quả phù hợp với biến được khai báo, nhưng không có giá trị (báo cáo alert()
undefined
đó là những gì xảy ra khi biến tồn tại, nhưng chưa được khởi tạo).
Ví dụ đầu tiên của bạn không sử dụng var
và do đó không có cẩu ở điểm bạn làm alert(box)
, không có biến nào ở tất cả có tên box
và do đó bạn nhận được uncaught reference error
.
Có rất nhiều, nhiều bài đăng ở đây trên SO mô tả chi tiết của cẩu. Bạn có thể thấy một danh sách dài của chúng ở đây: https://stackoverflow.com/search?q=javascript+variable+hoisting nơi bạn sẽ tìm thấy giải thích thêm về cẩu nâng.
Lưu ý: các khai báo chức năng cũng được treo để một số bài đăng bạn tìm thấy sẽ về khai báo hàm thay vì khai báo biến, mặc dù khái niệm này khá giống nhau.
Đọc về hộp "hoisting" – elclanrs
gọi, trước khi bạn đã xác định hộp, nó không tồn tại, nó chỉ tồn tại khi bạn xác định nó, cho dù 'nó' có giá trị hay không. – saj
Hiểu biết của bạn là khá nhiều ở đó :) –