2010-07-27 32 views
7

Có thể ai đó vui lòng cho tôi biết lý do lần đăng nhập cuối cùng của 'x' bằng 0 và không 1. Tôi nghĩ vì nó được khai báo bên ngoài một hàm có phạm vi toàn cục và sau đó trong hàm, giá trị của nó được đặt đến 1 và giá trị đó sẽ vẫn là giá trị toàn cầu? Tôi biết giá trị 'x' đầu tiên bên trong hàm là toàn cầu vì bất kỳ biến nào được khai báo mà không có từ khóa var trở thành một thuộc tính của đối tượng cửa sổ. Rất cám ơnVà tôi nghĩ rằng tôi hiểu phạm vi

var x = 0; //global variable 

function y(){ 
    x = 1; 
    log("1. %n ", x);//1. 1 

    var x = 2; 
    log("2. %n ", x);//2. 2 
} 

y(); 
log("3. %n ", x);//3. 0 

Trả lời

6

Tuyên bố var là chủ đề của cẩu, khi mã của bạn được đánh giá nó thực sự trông như thế này:

var x = 0; //global variable 
function y(){ 
    var x; // local!! 

    x = 1; 
    log("1. %n ", x);//1. 1 

    x = 2; 
    log("2. %n ", x);//2. 2 
} 

y(); 
log("3. %n ", x);//3. 0 

Ngay trước y được thực thi, một bối cảnh thực hiện mới được thiết lập, và quá trình Variable Instantiation mất đặt trước chức năng được thực hiện.

Đó là một trong những lý do tại sao JSLint đề xuất chỉ một câu lệnh var cho mỗi hàm, giống với những gì đang thực sự xảy ra.

+0

Cảm ơn người đàn ông. Luôn luôn có thể trả lời bạn cho câu trả lời. – screenm0nkey

+0

Bạn được chào đón @Nick, tôi rất vui được trợ giúp! – CMS

1

tôi nghĩ, nhưng không thể xác nhận qua spec ECMAScript, rằng "var x = 2" dòng được quét tại thời gian định nghĩa hàm, và phạm vi địa phương "x" được áp dụng cho toàn bộ , không chỉ sau vị trí của dòng "var x" trong hàm.

Dưới đây là một trường hợp đơn giản thử nghiệm (thử nghiệm qua jsdb):

js>x = 0; 
0 
js>function foo(k) { x=k; } 
js>function bar(k) { var x=k; } 
js>function baz(k) { x=k; var x=2; } 
js>foo(1) 
js>x 
1 
js>bar(2) 
js>x 
1 
js>baz(3) 
js>x 
1 

Bạn sẽ lưu ý rằng chức năng duy nhất ở đây có ảnh hưởng đến toàn cầu "x" là foo(). Hàm bar() rõ ràng chỉ ảnh hưởng đến x cục bộ. Nhưng hàm baz() chỉ ảnh hưởng đến x cục bộ. Bạn sẽ nghĩ rằng nhiệm vụ x=k; sẽ ảnh hưởng đến toàn cầu x, vì nó xảy ra "trước" tuyên bố tiếp theo var x = 2; mà rõ ràng ảnh hưởng đến biến cục bộ x. Nhưng tôi khá chắc chắn rằng nếu bạn làm var x trong một hàm, trình thông dịch sẽ thấy nó và áp dụng nó cho tất cả sử dụng x trong phạm vi đó. Tình huống tương tự như của bạn.

5

Biến x bên trong hàm được tạo ra ngay lập tức khi chức năng được thực hiện và không chỉ khi phù hợp với variable statement đạt được:

Nếu tuyên bố biến xảy ra bên trong một FunctionDeclaration, các biến là được định nghĩa với phạm vi hàm địa phương trong hàm đó […]. Các biến được tạo khi phạm vi thực hiện được nhập. […] Các biến được khởi tạo thành không xác định khi được tạo. [...]

Bạn có thể thấy rằng x là bước đầu undefined khi thêm một cuộc gọi log ở phía trước của chuyển nhượng đầu tiên:

function y(){ 
    log("0. " + x);//0. undefined 
    x = 1; 
    log("1. " + x);//1. 1 
    var x = 2; 
    log("2. " + x);//2. 2 
} 

Điều đó có nghĩa cả hai nhiệm vụ bên trong hàm tham khảo x trong function- phạm vi địa phương và không phải là x trong phạm vi toàn cầu.

+0

+1 có và xem câu trả lời của CMS cũng vì nó sử dụng từ "cẩu" bị thiếu. –

+0

+1 Cảm ơn người đàn ông.Chỉ khi tôi nghĩ rằng tôi biết những gì đang xảy ra với JavaScript, cái gì đó khác khiến tôi bướng bỉnh. Cảm ơn câu trả lời tuyệt vời. – screenm0nkey

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