2012-07-26 32 views
5

Ai có thể giải thích, tại sao mã js tiếp theo tăng hai cửa sổ cảnh báo bằng văn bản 'string1' thay vì tăng thứ hai với văn bản 'không xác định' bên trong ?? Nếu cả hai biến được mô tả trong phạm vi cùng ..Biến được xác định trong phạm vi toàn cầu với tên giống nhau

var a = 'string1'; 
alert(a); 
var a; 
alert(a);​ 

http://jsfiddle.net/FdRSZ/1/

Cảm ơn

+0

+1, câu hỏi thú vị. –

+0

Các biến cục bộ cũng nên thực hiện hành vi tương tự này. – hugomg

Trả lời

6

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 để dnMã đị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 varAlreadyDeclaredfalse, sau đó
    • Gọi env của CreateMutableBinding phương pháp bê tông qua dnconfigurableBindings như các đối số.
    • Gọi SetMutableBinding phương pháp bê tông env của truyền dn, undefinednghiê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.

3

Đó là bởi vì thứ hai var a không phải là một khai báo biến riêng biệt. Theo như các thông dịch viên javascript có liên quan nó là giống như một trong những đầu tiên.

3

var có nghĩa là "Phạm vi biến này cho hàm này" không "Đặt giá trị của biến này thành undefined".

Nếu biến đã được scoped đến chức năng sau đó var foo nghĩa giống như chỉ đơn giản foo

4

Thats vì JavaScript thực hiện điều gì đó được gọi là cẩu nâng. Trong thực tế, JS của bạn trông như thế này:

var a; // hoisted -> declared on top 

a = 'string1'; 
alert(a); 
alert(a); 

Xem How Good C# Habits can Encourage Bad JavaScript Habits để biết thêm chi tiết về cách JavaScript hoạt động.

+0

Cảm ơn bạn đã liên kết, một liên kết hữu ích –

Các vấn đề liên quan