2015-08-05 14 views
9

Nếu từ khóa let giới thiệu việc triển khai đúng phạm vi khối, thì var có còn trường hợp sử dụng không? Tôi đang xem xét điều này từ một quan điểm thiết kế phần mềm chứ không phải là một cú pháp, "tốt bạn có thể" quan điểm.Trường hợp sử dụng cho var trong ES6 là gì?

+0

liên quan: http://stackoverflow.com/questions/762011/javascript-let-keyword- vs-var-keyword – Marvin

+1

Tôi hiểu sự khác biệt, tôi chỉ đang cố gắng chọn bộ não lập trình ngay bây giờ vì lý do 'var' sẽ không chỉ để lại việc sử dụng phổ biến mãi mãi. –

+0

Có thể trùng lặp của [Sự khác nhau giữa việc sử dụng "let" và "var" để khai báo biến là gì?] (Https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and- var-to-declaration-a-variable) –

Trả lời

8

Nếu từ khóa let giới thiệu việc triển khai đúng phạm vi khối, thì var còn có trường hợp sử dụng không?

Có thể có một trường hợp sử dụng: let khai báo trong phạm vi toàn cầu không tạo thuộc tính trên đối tượng chung. Ví dụ:

"use strict"; // for chrome 
 
var foo = 42; 
 
let bar = 21; 
 
console.log('window.foo (var)', window.foo); // 42 
 
console.log('window.bar (let)', window.bar); // undefined

Từ 8.1.1.4 Global Environment Records

Các thành phần đối tượng Environment Record của một Ghi Môi trường toàn cầu bao gồm các cam kết ràng buộc đối với tất cả built-in globals (clause 18) và tất cả các ràng buộc được giới thiệu bởi một FunctionDeclaration, GeneratorDeclaration hoặc VariableStatement chứa trong mã toàn cầu. Các ràng buộc cho tất cả các khai báo ECMAScript khác trong mã toàn cầu được chứa trong thành phần khai báo môi trường bản ghi của bản ghi môi trường toàn cầu.

Tuy nhiên, điều này cũng có thể dễ dàng được giải quyết bằng cách tạo ra một biến rõ ràng toàn cầu sử dụng bằng cách gán cho đối tượng toàn cầu trực tiếp:

window.foo = 42; 

Điều này cũng sẽ là cách duy nhất để tạo ra các lớp học toàn cầu btw , bởi vì tuyên bố class có cùng hành vi.

(Lưu ý: Tôi không ủng hộ việc sử dụng các biến toàn cục)


Có cấu trúc cú pháp mà bạn chỉ có thể sử dụng var, nhưng đó là hơn một hệ quả của cách spec phát triển và doesn' t thực sự phục vụ bất kỳ mục đích thực tế nào. Ví dụ:

if (true) 
    var foo = 42; // valid but kind of useless or bad design 

// vs 

if (true) 
    let foo = 42; // invalid 

Khối phạm vi không chỉ là tính năng hữu ích mặc dù. Các temporal dead zone là một tính năng tiện dụng để tìm lỗi dễ dàng hơn.So sánh:

var foo = 42; 
function bar() { 
    console.log(foo); // undefined 
    var foo = 21; 
} 
bar(); 

// vs 

var foo = 42; // or `let`, doesn't matter 
function bar() { 
    console.log(foo); // ReferenceError, temporal dead zone 
    let foo = 21; 
} 
bar(); 

Bạn gặp lỗi tham chiếu khi cố gắng truy cập biến số let chưa được khởi tạo.

+1

Từ những gì bạn đang nói, có vẻ như 'let' giới thiệu một môi trường nghiêm ngặt hơn cho logic nghiệp vụ.Đó là ý kiến ​​của tôi rằng nó phải pha sử dụng 'var' ra theo thời gian trong các vòng tròn giác ngộ. –

3

let không thể được sử dụng trong phạm vi toàn cầu nhưng. var có thể.

Đây là những gì bạn nhận được từ Chrome khi bạn thử một let bên ngoài toàn cầu của chế độ nghiêm ngặt:

tờ khai

Block-scoped (let, const, chức năng, lớp) chưa được hỗ trợ bên ngoài chế độ nghiêm ngặt

+0

Đây có phải là kết quả từ bản thân thông số kỹ thuật hoặc hiện tại không? –

+1

@KamuelaFranco: Rõ ràng là hạn chế thực hiện – Bergi

0

Thực tế có một số trường hợp sử dụng mà tôi đã tìm thấy cho chính mình.

Đôi khi bạn có thể muốn khai báo biến trong try-catch như vậy:

try { 
    //inits/checks code etc 
    let id = getId(obj); 

    var result = getResult(id); 
} catch (e) { 
    handleException(e); 
} 

//use `result` 

Với let tờ khai result sẽ trước khi try, đó là một chút sớm và ra khỏi bối cảnh cho các tác giả và người đọc của mã.

Tương tự là cho tờ khai điều kiện:

if (opts.re) { 
    var re = new RegExp(opts.re); 
    var result = match(re); 
    if (!result) return false; 
} 

//use result here safely 

Với let mã này sẽ là một chút buộc phải phàn nàn "phong cách tốt", mặc dù đó có thể là không thực tế.

Ngoài ra tôi có thể tưởng tượng trường hợp bạn muốn sử dụng các biến thuộc khối loop:

for (var x = 0; x < data.width; x++) { 
    if (data[x] == null) break; 
    //some drawing/other code 
} 

//here we have the `x` pointing to the end of data 

người với tiêu chuẩn vẻ đẹp cao có thể xem xét rằng lộn xộn, Bản thân tôi thích let s, nhưng nếu mã Tôi chỉnh sửa đã chứa var s - điều đó là tự nhiên để sử dụng chúng và làm cho việc mã hóa dễ dàng hơn.

0

Một trường hợp sử dụng có giá trị: hiệu suất lặp lại.

Thông số kỹ thuật có let trong đầu lặp for xây dựng môi trường hoàn toàn mới cho mỗi lần lặp (§ 13.7.4.9). Điều này là để làm cho việc đóng cửa xây dựng trong vòng dễ dàng hơn. Ngược lại, var xây dựng một môi trường cho toàn bộ vòng lặp.

tôi hiển thị let như thực hiện một vòng lặp for 3-4 lần chậm trong cả hai nút và trình duyệt (performance test here):

const iterations=1000000000; // 1 billion iterations 
for(var i=0;i<iterations;i++); // 1.558 seconds 
for(let i=0;i<iterations;i++); // 4.986 seconds (*** 3-4 times slower than the others) 
var i;(i=0;i<iterations;i++); // 1.381 seconds 
let i;(i=0;i<iterations;i++); // 1.36 seconds 
var i=0;(;i<iterations;i++); // 1.37 seconds 
let i=0;(;i<iterations;i++); // 1.389 seconds 

Sử dụng var gây ô nhiễm môi trường xung quanh chức năng. Sử dụng let ngoài vòng lặp ngăn chặn hiệu suất trúng nhưng vẫn gây ô nhiễm môi trường khối xung quanh.

Nếu bạn muốn có một lần lặp biến vòng lặp cục bộ mà không thực hiện đánh bạn có thể sử dụng thành ngữ đau đớn này:

{let i=0;for(;i<100;i++){ 
    console.log(i); // iteration code here 
}} 
i; // ReferenceError: i is not defined 
+0

Thông số kỹ thuật có cùng điều xảy ra trên 'cho in' và' cho các vòng lặp. Trong nút, tôi hiển thị 'var' nhanh hơn 50% trên' cho in' và cùng tốc độ trên 'for of'. Trong các tiêu chí trình duyệt, chúng dường như luôn có cùng tốc độ. Nó không rõ ràng với tôi tại sao chúng khác với một vòng lặp 'for' bình thường và thay đổi trong các môi trường khác nhau. [cho trong perftest] (http://jsbench.github.io/#af642344be06436a331f626e73c0aaa9)/[cho của perftest] (http://jsbench.github.io/#628087cbe1c795ae44a74c9d3565b50b) – Lycan

+0

Nó chỉ là một vấn đề thời gian trước khi những điều này nhận được được tối ưu hóa. Nếu không cần phạm vi được tạo trên mỗi lần lặp, thì trình biên dịch tối ưu hóa sẽ có thể loại bỏ nó. Thông số kỹ thuật không đáng tin cậy để xác định hiệu suất, bởi vì chi tiết triển khai có thể khác với chi tiết và tối ưu hóa có thể thay đổi hoàn toàn mọi thứ. –

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