What is the use case for var in ES6?

前端 未结 4 1188
既然无缘
既然无缘 2020-11-27 07:24

If the let keyword introduces a proper implementation of block scope, does var any longer have a use case? I am looking at this from a software des

相关标签:
4条回答
  • 2020-11-27 07:43

    let can't be used in global scope yet. var can.

    This is what you get from Chrome when you try a global let outside of strict mode:

    Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

    0 讨论(0)
  • 2020-11-27 07:44

    You can use var if you want to deconstruct something into the function scope, for example a conditional:

    if (Math.random() > 0.5)
      var {a,b} = {a: 1, b: 2}
    else 
      var {a,b} = {a: 10, b: 20}
    
    // Some common logic on a and b
    console.log(a, b)
    

    With let you would have to write something like

    let result;
    
    if (Math.random() > 0.5)
      result = {a: 'foo', b: 'bar'}
    else 
      result = {a: 'baz', b: 'qux'}
    
    // Using const might make more sense here
    let {a, b} = result; 
    // Some common logic on a and b
    console.log(a,b)
    
    0 讨论(0)
  • 2020-11-27 07:56

    Practically there are some use-cases I found for myself.

    Sometimes you may want to declare variable in try-catch like so:

    try {
        //inits/checks code etc
        let id = getId(obj);
    
        var result = getResult(id);
    } catch (e) {
        handleException(e);
    }
    
    //use `result`
    

    With let the result declaration would be before try, which is a bit early and out of context for the author and a reader of the code.

    Same is for conditional declarations:

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

    With let this code would be a bit forced to complain "good style", though that might be impractical.

    Also I can imagine the case where you would like to use variables belonging to the loop block:

    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
    

    Someone with high beauty standards may consider that untidy, I myself prefer lets, but if the code I edit already contains vars - that is natural to use them and makes coding easier.

    0 讨论(0)
  • 2020-11-27 08:06

    If the let keyword introduces a proper implementation of block scope, does var any longer have a use case?

    There could be one use case: let declarations in global scope don't create a property on the global object. Example:

    "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

    From 8.1.1.4 Global Environment Records

    The object Environment Record component of a global Environment Record contains the bindings for all built-in globals (clause 18) and all bindings introduced by a FunctionDeclaration, GeneratorDeclaration, or VariableStatement contained in global code. The bindings for all other ECMAScript declarations in global code are contained in the declarative Environment Record component of the global Environment Record.

    However, this can also easily be solved by creating an explicit global variable using by assigning to the global object directly:

    window.foo = 42;
    

    This would also be the only way to create global classes btw, because the class declaration has the same behavior.

    (Note: I'm not advocating the use of global variables)


    There are syntax constructs where you can only use var, but that's more a consequence of the how the spec evolved and doesn't really serve any practical purpose. For example:

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

    Block scope is not the only useful feature though. The temporal dead zone is another handy feature to find bugs more easily. Compare:

    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();
    

    You get a reference error when trying to access a let variable that wasn't initialized yet.

    0 讨论(0)
提交回复
热议问题