2012-07-12 47 views
8

Nếu tôi làm điều này:Local Javascript Phạm vi vấn đề

var a = 0; 

(function() { 
    var a = a; //want to make local a = global a 
    ++a; 
    console.log("fn",a); 
})(); 

console.log(a);​ 

Đầu ra là:

fn NaN 
0 

Tại sao a bên trong tự chức năng thực hiện trở thành NaN?

Tôi biết nó hoạt động tốt nếu tôi làm:

(function() { 
    var b = a; 
    ++b; 
    console.log("fn",b); // fn 1 
})(); 

Nhưng nếu tôi đi theo con đường của phiên bản đầu tiên, nó có vấn đề NaN.

Tại sao điều này lại xảy ra?

+0

tôi không chắc chắn lý do tại sao nó thực hiện nhưng tôi đã thử sử dụng 'var a = window.a' và nó hoạt động phù hợp – Ibu

+0

@Ibu hmmm là lẻ ... – Neal

+0

vì tất cả biến toàn cầu nằm trong phạm vi cửa sổ – jagm

Trả lời

10

var a = a; thực sự là var a; a = a; do cẩu nâng. Điều này có nghĩa là tại thời điểm gán bài cũ a đã bị bóng mờ bởi cái mới (là undefined).

Cách dễ nhất để tránh các vấn đề như vậy là đi qua các giá trị như một tham số:

(function (a) { 
    ++a; 
    console.log("fn",a); 
})(a); 

Trong trường hợp a là một biến toàn cục bạn cũng có thể sử dụng var a = window.a; như woz suggested - nhưng kể từ khi có các biến toàn cục thường là một là ý tưởng tồi hơn ở lại với các thông số.

+0

Vậy làm thế nào Tôi làm cho nó để biến địa phương của tôi và biến toàn cầu bằng nhau ở đầu phạm vi chức năng địa phương? Tôi có cần sử dụng biến tạm thời không? – Neal

+1

Xem chỉnh sửa của tôi. Bạn không thể sử dụng một biến tạm thời cho điều này vì không có vấn đề gì bạn làm, ngay khi có 'var a' trong hàm của bạn, bên ngoài' a' không thể truy cập được nữa. – ThiefMaster

+0

Ooohh Tôi quên thông số :-P Duuuuh. '+ 1' – Neal

0

có một cẩu biến trong javascript, do đó, mã của bạn trong thực hiện trông như sau:

(function() { 
    var a; 
    a = a; //want to make local a = global a 
    ++a; 
    console.log("fn",a); 
})(); 

vậy, trước tiên bạn phải biến cục bộ một là không xác định và sau đó bạn gán không xác định để biến một

5

Các a biến bên trong biểu thức hàm của bạn bóng biến số a được khai báo trên phạm vi bên ngoài.

Nó trở thành NaN, vì trong sự phân công:

var a = a; 

Quyền-side a nó thực sự đề cập đến a trong phạm vi địa phương.

Tuyên bố biến được thực hiện trước khi chức năng thực sự bắt đầu được thực hiện, điều này thường được gọi là 'kéo'.

Vì nó biến tương tự, nó giữ giá trị undefined, và khi bạn cố gắng thêm bất kỳ số giá trị này, nó trở nên NaN:

console.log(undefined + 0); 
2

Trong JavaScript, dòng điện execution context (trong đó bao gồm những thứ như phạm vi biến đổi) được thiết lập trước khi mã của bạn bắt đầu thực thi.

Điều này có ý nghĩa với bạn là tên biến cục bộ của bạn được phân bổ trước tiên.Do cẩu, nhãn từ các câu hỏi varở bất kỳ đâu trong hàm được khởi tạo thành không được xác định trong ngữ cảnh thực thi hiện tại. (Báo cáo chức năng cũng được khởi tạo trong bước này.)

Tiếp theo, mã của bạn thực sự bắt đầu thực thi. Nhãn a đã được đặt trước trong ngữ cảnh thực hiện hiện tại, do đó, var a = a; chỉ cần gán a địa phương (chính là chưa xác định) cho chính nó.

var a = window.a hoạt động vì bạn tránh vấn đề phạm vi bằng cách truy cập trực tiếp phạm vi toàn cầu. Tuy nhiên, điều này không hoạt động trong môi trường không phải trình duyệt (như Nút) vì không có window; đối tượng chung trong Nút là global.