2013-06-12 44 views
10

Mã bên dưới là mã JavaScript. Tôi đang cố gắng hiểu phạm vi chức năng trong JavaScript và theo dõi bài viết trên here. Tôi đang tạo lại mã bên dưới -Hiểu phạm vi hàm JavaScript

var cow = "purple"; // just a random cow 

var f = function (x) { 
    var r = 0; 
    cow = "glue"; 
    if (x > 3) { 
     var cow = 1; // a local variable 
     r = 7; 
    } 
    return r; 
}; 

var z = f(2); 
alert(cow); // returns purple 

Tôi không hiểu tại sao chuỗi "tím" được cảnh báo. Dòng cow = "glue"; nên đặt giá trị của biến bò thành "keo". Nếu tôi loại bỏ khối nếu, và sau đó cảnh báo bò trong tuyên bố cuối cùng, tôi thấy rằng chuỗi "keo" được cảnh báo.

Khi f (2) được gọi, nếu khối mã không được nhập và không có gì trong đó được thực hiện, vậy tại sao tôi thấy kết quả khác nhau? tức là tại sao con bò cảnh báo trong câu cuối cùng trả lại chuỗi "màu tía" bây giờ?

Trả lời

4

Javascript không có phạm vi chặn (ngoại trừ trong các khối catch).
Tất cả các câu hỏi varhoisted ở đầu hàm chứa.

Do đó, cow đề cập đến biến cục bộ ở bất kỳ đâu trong hàm, ngay cả khi if không bao giờ thực thi.

+1

Thực ra, ngay cả các khối 'catch' cũng có phạm vi riêng (* môi trường biến *). Xem [Tại sao các mệnh đề bắt có môi trường * ngôn ngữ * của riêng mình?] (Http://stackoverflow.com/q/15034864/1048572) để biết chi tiết – Bergi

9

Tuyên bố biến bên trong các hàm luôn được treo lên trên cùng. Vì vậy, mã của bạn là thực sự:

var f = function (x) { 
    var cow, r; 
    r = 0; 
    cow = "glue"; 
    if (x > 3) { 
     cow = 1; // a local variable 
     r = 7; 
    } 
    return r; 
}; 

Bên trong chức năng bạn luôn gán cho địa phươngcow, không bao giờ là toàn cầu.

+0

Tôi nghĩ bạn có nghĩa là 'var cow, r' there, not' var f, r' –

+0

@ ben336 Vâng, tôi đã khắc phục điều đó một lúc trước. Có thể trình duyệt của bạn không nhận được thông báo chỉnh sửa? Đôi khi điều websocket không thành công ... – bfavaretto

+0

vâng, hãy xem ngay bây giờ. Làm việc với một kết nối mạng spotty ngay hôm nay. Cũng không thấy rằng những người khác đã trả lời cho đến khi tôi đăng tải của tôi. –

5

Hai điều cần hiểu ở đây là các biến Javascript được treo lên đầu phạm vi của chúng và javascript không có phạm vi chặn.

Vì vậy

  1. Tất cả các biến trong một phạm vi được coi là tuyên bố vào đầu phạm vi
  2. một tuyên bố nếu không tạo ra một phạm vi mới.

Vì vậy, ví dụ bạn là tương đương với

var cow = "purple"; // just a random cow 

var f = function (x) { 
    var cow, r = 0; 
    cow = "glue"; 
    if (x > 3) { 
     cow = 1; // a local variable 
     r = 7; 
    } 
    return r; 
}; 

var z = f(2); 
alert(cow); // returns purple 

Việc kê khai var trong câu lệnh if được kéo lên đến đỉnh. Tại thời điểm đó, tất cả các tham chiếu bò trong hàm tham chiếu đến biến bò cục bộ, thay vì bò từ phạm vi bên ngoài.

+0

không có var ở phía trước của bò = keo trong hướng dẫn, tôi không biết nếu đó là một lỗi của tác giả – Ibu

+0

không có của nó không phải là một lỗi nhất thiết, nếu điểm là để hiển thị như thế nào js phạm vi hoạt động. tuyên bố một var trong câu lệnh if là thực hành xấu vì nó khó hiểu, nhưng không sai " –

+0

+1" để chỉ ra rằng nếu khối không tạo ra phạm vi mới, điều này có thể là nguồn gốc của sự hiểu lầm OP. – bfavaretto

4

Bạn đã không thực sự đọc bài viết đó phải không? Nó tuyên bố rõ ràng

cow được chuyển thành "glue" khi bạn gọi f(2)? Không, cow an toàn trong mã ở trên vì tuyên bố var cow bên trong khối nếu áp dụng cho toàn bộ chức năng. Nó có nghĩa là cow là một biến địa phương cho toàn bộ hàm.

Tuy nhiên, khi bạn xóa khối nếu bạn cũng xóa khai báo biến bên trong nó và nhiệm vụ sẽ nhắm mục tiêu biến toàn cầu.