2013-06-04 32 views
18

Có điều gì giống như thực tiễn tốt nhất khi nói đến khai báo biến trong javascript trước khi gán giá trị cho chúng không? Đôi khi nó là cần thiết vì lý do phạm vi, nhưng nếu phạm vi không quan trọng?Thực hành tốt nhất để khai báo biến javascript trống

// Declare first 
(function() { 
    var foo = 'bar', 
     a = 500, 
     b = 300, 
     c; 

    // Some things get done here with a and b before c can use them... 

    c = a * b;  

    // c is now ready to use... 
    doSomething(c); 
}()); 

// Declare when needed 
(function() { 
    var foo = 'bar', 
     a = 500, 
     b = 300; 

    // Some things get done here with a and b before c can use them... 

    var c = a * b; 

    // c is now ready to use... 
    doSomething(c); 
}()); 

Và tôi cũng đang tự hỏi thực hành tốt nhất cho một cái gì đó tương tự với đối tượng trực là những gì:

// Add property with null assigned to it 
var myObj = { 
    foo: null, 

    doSomething: function() { 
     this.foo = 'bar'; 
    } 
}; 

// Property gets added when value is set 
var myObj = { 
    doSomething: function() { 
     this.foo = 'bar'; 
    } 
}; 
+1

Chủ yếu chỉ là vấn đề về phong cách. Crockford khuyên bạn nên khai báo tất cả các biến ở đầu phạm vi và đôi khi giúp xóa một số quan niệm sai lầm phổ biến (ví dụ: khai báo 'var' bên trong' for' loop thực sự thuộc phạm vi bên ngoài 'for'). –

+0

@ FabrícioMatté Cảm ơn! Thậm chí không nghĩ về các vòng lặp for', nhưng nó có ý nghĩa. – Hendrik

Trả lời

17

Nó chủ yếu là một vấn đề của phong cách.

Khi var khai báo tự động hoisted up lên đầu phạm vi, bạn nên đặt chúng ở đầu phạm vi của chúng để bạn có thể đọc mã gần hơn cách trình thông dịch sẽ thực thi nó.

Khai báo biến ở đầu phạm vi của chúng là Crockford's recommendation. Và nó có ý nghĩa như nó làm sáng tỏ một số quan niệm sai lầm phổ biến.

Ví dụ:

for (var i = 0; i < 3; i++) { 
    setTimeout(function() { 
     console.log(i); 
    }, 0); 
} 

Kể từ var có chức năng phạm vi, tất cả lặp (và các chức năng bên trong của chúng) tham khảo với cùng i. Vì tất cả ba hàm thời gian sẽ thực thi sau khi vòng lặp kết thúc, đoạn mã trên ghi nhật ký 3 ba lần.

Bây giờ đối với những người có trải nghiệm phạm vi khối, hành vi trên không rõ ràng. Viết lại đoạn mã:

var i; 
for (i = 0; i < 3; i++) { 
    // ... 
} 

Hiện tại, i được khai báo trong phạm vi toàn cục, chính xác như đoạn trước. Tuy nhiên, điều này là rõ ràng hơn về điều đó.


Một quan niệm sai lầm:

(function() { 
    if (true) { 
     var foo = 1; 
    } else { 
     var foo = 1; 
    } 
}()); 

Một lần nữa, trong khối scoped languages¹ ở trên là hoàn toàn hợp lệ. Tuy nhiên, như var tờ khai được treo lên đến đỉnh của phạm vi chức năng hiện tại thời gian phân tích, phía trên là tương đương với:

(function() { 
    var foo; 
    var foo; 
    if (true) { 
     foo = 1; 
    } else { 
     foo = 1; 
    } 
}()); 

Biến được khai báo hai lần. Hầu hết các trình duyệt sẽ chỉ bỏ qua khai báo thứ hai và mã sẽ "hoạt động", nhưng các công cụ phân tích mã tĩnh như JSHint sẽ hét lên với bạn.

Bạn có thể viết lại nó chỉ với một lời tuyên bố và nó là hoàn toàn hợp lệ:

(function() { 
    if (true) { 
     var foo = 1; 
    } else { 
     foo = 1; 
    } 
}()); 

Nhưng lập trình giống như chứng OCD như tôi sẽ tìm thấy nó khá xấu xí. Vì vậy, một lần nữa, tuyên bố ở trên cùng của phạm vi:

(function() { 
    var foo; 
    if (true) { 
     foo = 1; 
    } else { 
     foo = 1; 
    } 
}()); 

Dường như gọn gàng hơn nhiều.


Một lần nữa, nó chủ yếu là vấn đề về phong cách. Cá nhân, nếu tôi có một chức năng khổng lồ, tôi ghét để cuộn tất cả các con đường lên chỉ để kiểm tra xem một biến đã được khai báo và thêm nó vào danh sách.Trong trường hợp đó, tôi có thể chỉ cần thêm một vài tờ khai var ở giữa chức năng (chống lại khuyến cáo của Crockford) mà cá nhân tôi thấy dễ đọc và duy trì hơn.

Vì đây là vấn đề về phong cách, chỉ cần đảm bảo giữ mã của bạn được duy trì và súc tích nhất có thể.


Ở phía bên kia của đồng xu, tôi sẽ thừa nhận rằng, cá nhân tôi, tôi đã bắt đầu và chủ yếu sử dụng var tờ khai khi biến được sử dụng đầu tiên. Đây là một khía cạnh của ngôn ngữ và bạn có thể sử dụng nó theo cách này mà không gặp vấn đề gì. Nhưng tôi cũng sẽ thừa nhận rằng, nếu tôi đã làm theo các khuyến nghị của Crockford ngay từ đầu, tôi đã có ít đau đầu hơn (như với các quan niệm sai được trình bày ở trên) và sẽ nắm bắt được khía cạnh phạm vi chức năng của JavaScript nhanh hơn nhiều.


¹ Lưu ý rằng JS 1,7 biến khối chỉnh phạm vi giới thiệu qua let, nhưng nó không được hỗ trợ rộng rãi được nêu ra.

+0

Để không làm cho mặt khác của câu hỏi quá cá nhân, tôi sẽ nhận xét rằng mã của riêng tôi không phải là dễ đọc nhất. Mặc dù, khi làm việc trong một dự án nhóm, hãy cố gắng xác định một số tiêu chuẩn sạch sẽ và hợp lý, đảm bảo rằng mã tuân thủ các tiêu chuẩn này - điều đó sẽ cung cấp khả năng bảo trì cao hơn. –

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