2012-04-18 42 views
10

Tôi chắc rằng tôi đã đọc một cuộc thảo luận về SO về điều này nhưng không thể tìm thấy nó. Đơn giản, có khuyết điểm nào để tuyên bố tăng vòng lặp for trong vòng khai báo của vòng lặp không? sự khác biệt giữa điều này là gì:Khai báo var bên trong Javascript để khai báo vòng lặp

function foo() { 
    for (var i=0; i<7; i++) { 
     // code 
    } 
} 

... và điều này:

function foo() { 
    var i; 
    for (i=0; i<7; i++) { 
     // code 
    } 
} 

Kể từ JS có phạm vi chức năng, một trong hai nên được tốt, phải không? Có trường hợp cạnh nào mà cách tiếp cận cũ sẽ gây ra vấn đề?

Nếu chúng giống hệt nhau, tại sao Crockford/JSLint tất cả, "Không có cách nào dawg", về nó?

+2

Bản sao có thể có của [Biến JavaScript khai báo bên ngoài hoặc bên trong vòng lặp?] (Http://stackoverflow.com/questions/3684923/javascript-variables-declare-outside-or-inside-loop) –

Trả lời

12

Đây là chính xác như nhau. Tất cả các biến cục bộ trong javascript đều có phạm vi hàm có nghĩa là chúng đang hoạt động cho toàn bộ hàm mà chúng được khai báo. Điều này thường phản trực giác đầu tiên vì hầu hết các ngôn ngữ dấu ngoặc nhọn đều có phạm vi thời gian sống của biến đó vào khối mà chúng được khai báo.

Một phần của nhà phát triển Javascript rất thích biểu mẫu thứ hai. Lý do là vì tất cả các biến có phạm vi hàm, bạn nên khai báo chúng ở mức hàm để làm cho thời gian sống rõ ràng ngay cả đối với những người không quen với Javascript. Đây chỉ là một phong cách và mặc dù không phải là một quy tắc cứng

EDIT

Lưu ý rằng với sự ra đời của ES6 let, bạn bây giờ có thể sử dụng để cho bên trong vòng lặp của bạn thật khối chỉnh phạm vi biến more details

for(let i = 1; i <= 5; i++) { 
    setTimeout(function(){ 
     console.log('Value of i : ' + i); 
    },100); 
} 
+0

Cũng có 'let' tương tự như' var' ở chỗ nó cũng cho một phạm vi cục bộ, nhưng nó khác ở chỗ nó nhận phạm vi khối. Nó không thể truy cập bên ngoài 'for' /' if'/'while', vv .. – 4castle

0

Cả hai đều giống hệt nhau.

+0

Không phải là câu trả lời rất hữu ích; câu hỏi là, cho rằng chúng có chức năng tương đương, tại sao quy tắc trong JSLint? JSLint rất đáng kinh ngạc về nhiều thứ, có tầm quan trọng đối với bạn có thể khác nhau, nhưng có phương pháp để điên rồ của nó. –

+0

JSLint nghĩa là không có gì. – Rob

+1

Lol nó có nghĩa là một cái gì đó ... có lẽ không nhiều nhưng đối với một noob như tôi nó giúp thiết lập thói quen tốt. –

7

Sự cố khi khai báo với var trong tiêu đề vòng lặp là nó lừa đảo. Nó trông như bạn đang khai báo một biến có phạm vi được giới hạn ở những for vòng lặp, khi nó thực sự tồn tại ở khắp mọi nơi trong phạm vi chức năng - bao gồm trước tuyên bố:

var i = 1; 
function foo() { 
    console.log(i);      // 'undefined' 
    for (var i=1; i<100; ++i) { 
    } 
} 

Mặc dù cuộc gọi console.log xảy ra trước tuyên bố của địa phương i, nó vẫn còn trong phạm vi cho nó bởi vì nó bên trong cùng một chức năng. Vì vậy, các địa phương i, mà chưa có bất kỳ giá trị được giao cho nó, là những gì được thông qua để log. Điều này có thể gây ngạc nhiên; nó chắc chắn không hiển nhiên đối với bất kỳ ai không quen thuộc với các quy tắc phạm vi Javascript.

Bắt đầu với ECMAScript 2015, có cách tốt hơn để khai báo biến: let. Các biến được khai báo với let là cục bộ cho khối chứa chúng, chứ không phải toàn bộ hàm. Vì vậy, phiên bản này của các mã trên sẽ in 1 như dự định:

let i=1; // could use var here; no practical difference at outermost scope 
function foo() { 
    console.log(i);    // 1 
    for (let i=1; i<100; ++i) { 
    } 
} 

Vì vậy, thực hành tốt nhất trong Javascript hiện đại là để khai báo các biến với let thay vì var. Tuy nhiên, nếu bạn đang mắc kẹt với một pre-ECMAScript 2015 thực hiện, nó là một chút ít khó hiểu để khai báo tất cả các biến ở trên cùng của hàm, thay vì chờ đợi cho đến khi sử dụng đầu tiên.

+0

Vì vậy, miễn là bạn đã quen thuộc với việc xử lý phạm vi của Js, thì tất cả đều tốt. –

+1

đó là lý do tại sao mọi người phải ngừng sử dụng 'var' –

+0

Cảm ơn lời nhắc, @SartherisStormhammer. Cập nhật để giải quyết sự sẵn có của 'let' trong ngôn ngữ hiện đại. –

1

Không có sự khác biệt, nhưng tôi thích cách thứ hai (mỗi Crockford) bởi vì nó một cách rõ ràng cho thấy rằng các biến bên ngoài có sẵn của vòng lặp for:

function() { 
    for(var i=0; i<7; i++) { 
     // code 
    } 

    // i is still in scope here and has value 7 
} 
0

Mã khối hai giống hệt nhau. Câu lệnh đầu tiên của vòng lặp for được thực thi trước khi vòng lặp for bắt đầu, vòng lặp đang chạy trong khi câu lệnh thứ hai là đúng, và câu lệnh thứ ba được chạy mỗi khi vòng lặp lặp lại một lần.

Điều này có nghĩa rằng

for(var i = 0; i < 8; i++) { 
    //some Code 
} 

giống hệt

var i = 0; 
for(;i < 8;) { 
    //some Code 
    i++; 
} 

(Các dấu chấm phẩy sau ( là bảo với máy tính i < 8 thực sự là tuyên bố thứ hai, không phải là lần đầu tiên).

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