tờ khai Variable (và tờ khai chức năng) là treo để phía trên cùng của phạm vi trong đó chúng xuất hiện. Các bài tập diễn ra tại chỗ. Mã này được giải thích một cách hiệu quả như thế này:
var a;
var a;
a = 'string1';
Ví dụ, hãy xem xét những gì sẽ xảy ra nếu bạn khai báo một biến bên trong một cơ thể if
tuyên bố:
console.log(myVar); //undefined (NOT a reference error)
if (something === somethingElse) {
var myVar = 10;
}
console.log(myVar); //10
Bởi vì JavaScript không có phạm vi khối, tất cả các tờ khai trong mỗi phạm vi được treo lên đầu phạm vi đó. Nếu bạn cố đăng nhập một số biến không được khai báo, bạn sẽ gặp lỗi tham chiếu. Ví dụ trên được giải thích như thế này:
var myVar; //Declaration is hoisted
console.log(myVar);
if (something === somethingElse) {
myVar = 10; //Assignment still happens here
}
console.log(myVar);
Vì vậy, ngay cả khi điều kiện để đánh giá false
, biến myVar
vẫn tiếp cận được. Đây là lý do chính mà JSLint sẽ cho bạn biết để di chuyển tất cả các khai báo lên đầu phạm vi mà chúng xuất hiện.
Cụ thể hơn một chút ... đây là những gì ECMAScript 5 spec có nói (đậm nhấn mạnh thêm):
Đối với mỗi VariableDeclaration và dVariableDeclarationNoIn trong đang, trong thứ tự văn bản nguồn làm
- Hãy để dn là Mã định danh trong d.
- Hãy varAlreadyDeclared thể là kết quả của việc gọi HasBinding bê tông phương pháp env của truyền dn làm đối số.
- Nếu varAlreadyDeclared là
false
, sau đó
- Gọi env của CreateMutableBinding phương pháp bê tông qua dn và configurableBindings như các đối số.
- Gọi SetMutableBinding phương pháp bê tông env của truyền dn,
undefined
và nghiêm ngặt như các đối số.
Vì vậy, nếu một ràng buộc đã tồn tại với các định danh chúng tôi đang cố gắng để ràng buộc bây giờ, không có gì xảy ra.
Nguồn
2012-07-26 14:03:03
+1, câu hỏi thú vị. –
Các biến cục bộ cũng nên thực hiện hành vi tương tự này. – hugomg