2017-03-22 51 views
8

Vì vậy, tôi đi qua một cái gì đó rất kỳ quặc khi làm việc trên một dự án javascript chỉ là bây giờ và ở đây là một luộc xuống ví dụ về tình hình tôi đang bối rối về:javascript phạm vi bảo mật vi phạm?

function doSomething() { 
    for(var d = 0;d < 10;d++) { 
     var shouldBePrivate = 5; 
    } 

    for(var d = 0;d < 10;d++) { 
     console.log(shouldBePrivate); 
    } 
} 

Khi bạn gọi doSomething() biến shouldBePrivate có thể truy cập trong vòng lặp thứ 2.

Điều đó không thể thực hiện được?

Trả lời

5

Tất cả các biến cục bộ trong javascript đều có phạm vi chức năng chứ không phải phạm vi khối (ít nhất trước ECMAScript 2015). Có nghĩa là các biến được khai báo bên trong hàm, có sẵn cho toàn bộ hàm.

Nội dung bạn đang giới thiệu là phạm vi chặn. Thật không may là phạm vi noblock trong Javascript cho đến ECMA2015. Từ ECMAScript 2015, bạn có thể khai báo các biến của mình với let chỉ có thể được tham chiếu trong khối và chúng sẽ chết ngay khi bạn thoát khỏi khối đó.

MDN docs says (with examples)

Khối Nội quy phạm trù

Với var

Biến khai báo với var không có phạm vi khối. Các biến được giới thiệu với một khối được đưa vào phạm vi hàm hoặc tập lệnh chứa, và các hiệu ứng của việc đặt chúng tồn tại vượt ra ngoài chính khối đó. Nói cách khác, các câu lệnh chặn không giới thiệu một phạm vi. Mặc dù các khối "độc lập" là cú pháp hợp lệ, bạn không muốn sử dụng các khối độc lập trong JavaScript, bởi vì chúng không làm những gì bạn nghĩ, nếu bạn nghĩ chúng làm bất cứ thứ gì như các khối như vậy trong C hoặc Java. Đối với

example: 

var x = 1; 
{ 
    var x = 2; 
} 
console.log(x); // logs 2 

này ghi 2 vì tuyên bố var x trong khối là trong phạm vi tương tự như báo cáo kết quả var x trước khi khối. Trong C hoặc Java, mã tương đương sẽ outputted 1.

Với let và const

Ngược lại, định khai báo với let và const làm có phạm vi khối:

let x = 1; 
{ 
    let x = 2; 
} 
console.log(x); // logs 1 
The x = 2 is limited in scope to the block in which it was defined. 
+1

Oh wow derp.Tôi đã không có ý tưởng javascript đã làm điều đó. Rất thú vị cảm ơn rất nhiều cho lời giải thích! – Parad0x13

2

Bạn đã vấp phải cái gì đó gọi là cẩu. Bởi vì tất cả các biến được phạm vi hàm chứa của chúng, các câu lệnh var được chuyển nội bộ lên đầu hàm.

Điều đó có nghĩa rằng người phiên dịch sẽ thực sự được chạy mã này:

function doSomething() { 
    var shouldBePrivate; 
    var d; 
    for(d = 0;d < 10;d++) { 
     shouldBePrivate = 5; 
    } 

    for(d = 0;d < 10;d++) { 
     // now it's easy to see why this works 
     console.log(shouldBePrivate); 
    } 
} 

Tính đến ES2015, bạn có thể sử dụng từ khóa let thay vì var được lexically scoped - tức là scoped trong khối, có nghĩa là let shouldBePrivate = 5; sẽ không tồn tại bên ngoài vòng lặp đầu tiên.

function doSomething() { 
    for(let d = 0;d < 10;d++) { 
     let shouldBePrivate = 5; 
    } 

    for(let d = 0;d < 10;d++) { 
     // Reference Error for shouldBePrivate 
     console.log(shouldBePrivate); 
    } 
} 
+0

Jeeze, thật thú vị tôi không biết. Cảm ơn bạn về thông tin! – Parad0x13

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