csdnceshi63
elliott.david
2009-04-17 20:09
采纳率: 25%
浏览 771

在 JavaScript 中使用"let"和"var"来声明变量有什么区别?

ECMAScript 6 introduced the let statement. I've heard it described as a "local" variable, but I'm still not quite sure how it behaves differently than the var keyword.

What are the differences? When should let be used over var?

转载于:https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable-in-jav

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

27条回答 默认 最新

  • weixin_41568196
    撒拉嘿哟木头 2016-11-23 23:42
    已采纳

    The difference is scoping. var is scoped to the nearest function block and let is scoped to the nearest enclosing block, which can be smaller than a function block. Both are global if outside any block.

    Also, variables declared with let are not accessible before they are declared in their enclosing block. As seen in the demo, this will throw a ReferenceError exception.

    Demo:

    var html = '';
    
    write('#### global ####\n');
    write('globalVar: ' + globalVar); //undefined, but visible
    
    try {
      write('globalLet: ' + globalLet); //undefined, *not* visible
    } catch (exception) {
      write('globalLet: exception');
    }
    
    write('\nset variables');
    
    var globalVar = 'globalVar';
    let globalLet = 'globalLet';
    
    write('\nglobalVar: ' + globalVar);
    write('globalLet: ' + globalLet);
    
    function functionScoped() {
      write('\n#### function ####');
      write('\nfunctionVar: ' + functionVar); //undefined, but visible
    
      try {
        write('functionLet: ' + functionLet); //undefined, *not* visible
      } catch (exception) {
        write('functionLet: exception');
      }
    
      write('\nset variables');
    
      var functionVar = 'functionVar';
      let functionLet = 'functionLet';
    
      write('\nfunctionVar: ' + functionVar);
      write('functionLet: ' + functionLet);
    }
    
    function blockScoped() {
      write('\n#### block ####');
      write('\nblockVar: ' + blockVar); //undefined, but visible
    
      try {
        write('blockLet: ' + blockLet); //undefined, *not* visible
      } catch (exception) {
        write('blockLet: exception');
      }
    
      for (var blockVar = 'blockVar', blockIndex = 0; blockIndex < 1; blockIndex++) {
        write('\nblockVar: ' + blockVar); // visible here and whole function
      };
    
      for (let blockLet = 'blockLet', letIndex = 0; letIndex < 1; letIndex++) {
        write('blockLet: ' + blockLet); // visible only here
      };
    
      write('\nblockVar: ' + blockVar);
    
      try {
        write('blockLet: ' + blockLet); //undefined, *not* visible
      } catch (exception) {
        write('blockLet: exception');
      }
    }
    
    function write(line) {
      html += (line ? line : '') + '<br />';
    }
    
    functionScoped();
    blockScoped();
    
    document.getElementById('results').innerHTML = html;
    <pre id="results"></pre>

    Global:

    They are very similar when used like this outside a function block.

    let me = 'go';  // globally scoped
    var i = 'able'; // globally scoped
    

    However, global variables defined with let will not be added as properties on the global window object like those defined with var.

    console.log(window.me); // undefined
    console.log(window.i); // 'able'
    

    Function:

    They are identical when used like this in a function block.

    function ingWithinEstablishedParameters() {
        let terOfRecommendation = 'awesome worker!'; //function block scoped
        var sityCheerleading = 'go!'; //function block scoped
    }
    

    Block:

    Here is the difference. let is only visible in the for() loop and var is visible to the whole function.

    function allyIlliterate() {
        //tuce is *not* visible out here
    
        for( let tuce = 0; tuce < 5; tuce++ ) {
            //tuce is only visible in here (and in the for() parentheses)
            //and there is a separate tuce variable for each iteration of the loop
        }
    
        //tuce is *not* visible out here
    }
    
    function byE40() {
        //nish *is* visible out here
    
        for( var nish = 0; nish < 5; nish++ ) {
            //nish is visible to the whole function
        }
    
        //nish *is* visible out here
    }
    

    Redeclaration:

    Assuming strict mode, var will let you re-declare the same variable in the same scope. On the other hand, let will not:

    'use strict';
    let me = 'foo';
    let me = 'bar'; // SyntaxError: Identifier 'me' has already been declared
    
    'use strict';
    var me = 'foo';
    var me = 'bar'; // No problem, `me` is replaced.
    
    </div>
    
    点赞 评论
  • csdnceshi59
    ℙℕℤℝ 2009-04-17 20:11

    Here's an explanation of the let keyword with some examples.

    let works very much like var. The main difference is that the scope of a var variable is the entire enclosing function

    This table on Wikipedia shows which browsers support Javascript 1.7.

    Note that only Mozilla and Chrome browsers support it. IE, Safari, and potentially others don't.

    点赞 评论
  • csdnceshi76
    斗士狗 2009-04-17 21:38

    There are some subtle differences -- let scoping behaves more like variable scoping does in more or less any other languages.

    e.g. It scopes to the enclosing block, They don't exist before they're declared, etc.

    However it's worth noting that let is only a part of newer Javascript implementations and has varying degrees of browser support.

    点赞 评论
  • csdnceshi67
    bug^君 2014-08-18 00:58

    Here's an example to add on to what others have already written. Suppose you want to make an array of functions, adderFunctions, where each function takes a single Number argument and returns the sum of the argument and the function's index in the array. Trying to generate adderFunctions with a loop using the var keyword won't work the way someone might naïvely expect:

    // An array of adder functions.
    var adderFunctions = [];
    
    for (var i = 0; i < 1000; i++) {
      // We want the function at index i to add the index to its argument.
      adderFunctions[i] = function(x) {
        // What is i bound to here?
        return x + i;
      };
    }
    
    var add12 = adderFunctions[12];
    
    // Uh oh. The function is bound to i in the outer scope, which is currently 1000.
    console.log(add12(8) === 20); // => false
    console.log(add12(8) === 1008); // => true
    console.log(i); // => 1000
    
    // It gets worse.
    i = -8;
    console.log(add12(8) === 0); // => true
    

    The process above doesn't generate the desired array of functions because i's scope extends beyond the iteration of the for block in which each function was created. Instead, at the end of the loop, the i in each function's closure refers to i's value at the end of the loop (1000) for every anonymous function in adderFunctions. This isn't what we wanted at all: we now have an array of 1000 different functions in memory with exactly the same behavior. And if we subsequently update the value of i, the mutation will affect all the adderFunctions.

    However, we can try again using the let keyword:

    // Let's try this again.
    // NOTE: We're using another ES6 keyword, const, for values that won't
    // be reassigned. const and let have similar scoping behavior.
    const adderFunctions = [];
    
    for (let i = 0; i < 1000; i++) {
      // NOTE: We're using the newer arrow function syntax this time, but 
      // using the "function(x) { ..." syntax from the previous example 
      // here would not change the behavior shown.
      adderFunctions[i] = x => x + i;
    }
    
    const add12 = adderFunctions[12];
    
    // Yay! The behavior is as expected. 
    console.log(add12(8) === 20); // => true
    
    // i's scope doesn't extend outside the for loop.
    console.log(i); // => ReferenceError: i is not defined
    

    This time, i is rebound on each iteration of the for loop. Each function now keeps the value of i at the time of the function's creation, and adderFunctions behaves as expected.

    Now, image mixing the two behaviors and you'll probably see why it's not recommended to mix the newer let and const with the older var in the same script. Doing so can result is some spectacularly confusing code.

    const doubleAdderFunctions = [];
    
    for (var i = 0; i < 1000; i++) {
        const j = i;
        doubleAdderFunctions[i] = x => x + i + j;
    }
    
    const add18 = doubleAdderFunctions[9];
    const add24 = doubleAdderFunctions[12];
    
    // It's not fun debugging situations like this, especially when the
    // code is more complex than in this example.
    console.log(add18(24) === 42); // => false
    console.log(add24(18) === 42); // => false
    console.log(add18(24) === add24(18)); // => false
    console.log(add18(24) === 2018); // => false
    console.log(add24(18) === 2018); // => false
    console.log(add18(24) === 1033); // => true
    console.log(add24(18) === 1030); // => true
    

    Don't let this happen to you. Use a linter.

    NOTE: This is a teaching example intended to demonstrate the var/let behavior in loops and with function closures that would also be easy to understand. This would be a terrible way to add numbers. But the general technique of capturing data in anonymous function closures might be encountered in the real world in other contexts. YMMV.

    点赞 评论
  • csdnceshi79
    python小菜 2015-03-06 10:41

    Here is an example for the difference between the two (support just started for chrome): enter image description here

    As you can see the var j variable is still having a value outside of the for loop scope (Block Scope), but the let i variable is undefined outside of the for loop scope.

    "use strict";
    console.log("var:");
    for (var j = 0; j < 2; j++) {
      console.log(j);
    }
    
    console.log(j);
    
    console.log("let:");
    for (let i = 0; i < 2; i++) {
      console.log(i);
    }
    
    console.log(i);

    </div>
    
    点赞 评论
  • weixin_41568208
    北城已荒凉 2015-05-27 10:16

    let can also be used to avoid problems with closures. It binds fresh value rather than keeping an old reference as shown in examples below.

    DEMO

    for(var i = 1; i < 6; i++) {
      document.getElementById('my-element' + i)
        .addEventListener('click', function() { alert(i) })
    }
    

    Code above demonstrates a classic JavaScript closure problem. Reference to the i variable is being stored in the click handler closure, rather than the actual value of i.

    Every single click handler will refer to the same object because there’s only one counter object which holds 6 so you get six on each click.

    General workaround is to wrap this in an anonymous function and pass i as argument. Such issues can also be avoided now by using let instead var as shown in code below.

    DEMO (Tested in Chrome and Firefox 50)

    'use strict';
    
    for(let i = 1; i < 6; i++) {
      document.getElementById('my-element' + i)
        .addEventListener('click', function() { alert(i) })
    }
    
    点赞 评论
  • weixin_41568134
    MAO-EYE 2015-06-02 20:59

    The accepted answer is missing a point:

    {
      let a = 123;
    };
    
    console.log(a); // ReferenceError: a is not defined
    
    点赞 评论
  • csdnceshi61
    derek5. 2015-08-11 00:35

    It also appears that, at least in Visual Studio 2015, TypeScript 1.5, "var" allows multiple declarations of the same variable name in a block, and "let" doesn't.

    This won't generate a compile error:

    var x = 1;
    var x = 2;
    

    This will:

    let x = 1;
    let x = 2;
    
    点赞 评论
  • csdnceshi59
    ℙℕℤℝ 2015-12-17 03:22

    May the following two functions show the difference:

    function varTest() {
        var x = 31;
        if (true) {
            var x = 71;  // Same variable!
            console.log(x);  // 71
        }
        console.log(x);  // 71
    }
    
    function letTest() {
        let x = 31;
        if (true) {
            let x = 71;  // Different variable
            console.log(x);  // 71
        }
        console.log(x);  // 31
    }
    
    点赞 评论
  • csdnceshi56
    lrony* 2016-01-17 15:11
    • Variable Not Hoisting

      let will not hoist to the entire scope of the block they appear in. By contrast, var could hoist as below.

      {
         console.log(cc); // undefined. Caused by hoisting
         var cc = 23;
      }
      
      {
         console.log(bb); // ReferenceError: bb is not defined
         let bb = 23;
      }
      

      Actually, Per @Bergi, Both var and let are hoisted.

    • Garbage Collection

      Block scope of let is useful relates to closures and garbage collection to reclaim memory. Consider,

      function process(data) {
          //...
      }
      
      var hugeData = { .. };
      
      process(hugeData);
      
      var btn = document.getElementById("mybutton");
      btn.addEventListener( "click", function click(evt){
          //....
      });
      

      The click handler callback does not need the hugeData variable at all. Theoretically, after process(..) runs, the huge data structure hugeData could be garbage collected. However, it's possible that some JS engine will still have to keep this huge structure, since the click function has a closure over the entire scope.

      However, the block scope can make this huge data structure to garbage collected.

      function process(data) {
          //...
      }
      
      { // anything declared inside this block can be garbage collected
          let hugeData = { .. };
          process(hugeData);
      }
      
      var btn = document.getElementById("mybutton");
      btn.addEventListener( "click", function click(evt){
          //....
      });
      
    • let loops

      let in the loop can re-binds it to each iteration of the loop, making sure to re-assign it the value from the end of the previous loop iteration. Consider,

      // print '5' 5 times
      for (var i = 0; i < 5; ++i) {
          setTimeout(function () {
              console.log(i);
          }, 1000);  
      }
      

      However, replace var with let

      // print 1, 2, 3, 4, 5. now
      for (let i = 0; i < 5; ++i) {
          setTimeout(function () {
              console.log(i);
          }, 1000);  
      }
      

      Because let create a new lexical environment with those names for a) the initialiser expression b) each iteration (previosly to evaluating the increment expression), more details are here.

    点赞 评论
  • weixin_41568131
    10.24 2016-02-08 15:03

    Previously there were only two scopes in JavaScript, i.e. functional and global. With 'let' keyword JavaScript has now introduced block-level variables.

    To have a complete understanding of the 'let' keyword, ES6: ‘let’ keyword to declare variable in JavaScript will help.

    点赞 评论
  • csdnceshi67
    bug^君 2016-02-23 18:35

    What's the difference between let and var?

    • A variable defined using a var statement is known throughout the function it is defined in, from the start of the function. (*)
    • A variable defined using a let statement is only known in the block it is defined in, from the moment it is defined onward. (**)

    To understand the difference, consider the following code:

    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, but undefined
    // l IS NOT known here
    
    function loop(arr) {
        // i IS known here, but undefined
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    
        for( var i = 0; i < arr.length; i++ ) {
            // i IS known here, and has a value
            // j IS NOT known here
            // k IS known here, but has a value only the second time loop is called
            // l IS NOT known here
        };
    
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    
        for( let j = 0; j < arr.length; j++ ) {
            // i IS known here, and has a value
            // j IS known here, and has a value
            // k IS known here, but has a value only the second time loop is called
            // l IS NOT known here
        };
    
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    }
    
    loop([1,2,3,4]);
    
    for( var k = 0; k < arr.length; k++ ) {
        // i IS NOT known here
        // j IS NOT known here
        // k IS known here, and has a value
        // l IS NOT known here
    };
    
    for( let l = 0; l < arr.length; l++ ) {
        // i IS NOT known here
        // j IS NOT known here
        // k IS known here, and has a value
        // l IS known here, and has a value
    };
    
    loop([1,2,3,4]);
    
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS NOT known here
    

    Here, we can see that our variable j is only known in the first for loop, but not before and after. Yet, our variable i is known in the entire function.

    Also, consider that block scoped variables are not known before they are declared because they are not hoisted. You're also not allowed to redeclare the same block scoped variable within the same block. This makes block scoped variables less error prone than globally or functionally scoped variables, which are hoisted and which do not produce any errors in case of multiple declarations.


    Is it safe to use let today?

    Some people would argue that in the future we'll ONLY use let statements and that var statements will become obsolete. JavaScript guru Kyle Simpson wrote a very elaborate article on why that's not the case.

    Today, however, that is definitely not the case. In fact, we need actually to ask ourselves whether it's safe to use the let statement. The answer to that question depends on your environment:

    • If you're writing server-side JavaScript code (Node.js), you can safely use the let statement.

    • If you're writing client-side JavaScript code and use a transpiler (like Traceur), you can safely use the let statement, however your code is likely to be anything but optimal with respect to performance.

    • If you're writing client-side JavaScript code and don't use a transpiler, you need to consider browser support.

    Today, Jun 8 2018, there are still some browsers that don't support let!

    enter image description here


    How to keep track of browser support

    For an up-to-date overview of which browsers support the let statement at the time of your reading this answer, see this Can I Use page.


    (*) Globally and functionally scoped variables can be initialized and used before they are declared because JavaScript variables are hoisted. This means that declarations are always much to the top of the scope.

    (**) Block scoped variables are not hoisted

    点赞 评论
  • csdnceshi65
    larry*wei 2016-05-19 11:41

    ECMAScript 6 added one more keyword to declare variables other the "const" other than "let".

    The primary goal of introduction of "let" and "const" over "var" is to have block scoping instead of traditional lexical scoping. This article explains very briefly difference between "var" and "let" and it also covers the discussion on "const".

    点赞 评论
  • csdnceshi50
    三生石@ 2016-07-01 08:22

    Now I think there is better scoping of variables to a block of statements using let:

    function printnums()
    {
        // i is not accessible here
        for(let i = 0; i <10; i+=)
        {
           console.log(i);
        }
        // i is not accessible here
    
        // j is accessible here
        for(var j = 0; j <10; j++)
        {
           console.log(j);
        }
        // j is accessible here
    }
    

    I think people will start using let here after so that they will have similar scoping in JavaScript like other languages, Java, C#, etc.

    People with not a clear understanding about scoping in JavaScript used to make the mistake earlier.

    Hoisting is not supported using let.

    With this approach errors present in JavaScript are getting removed.

    Refer to ES6 In Depth: let and const to understand it better.

    点赞 评论
  • csdnceshi54
    hurriedly% 2016-07-08 00:21

    let is interesting, because it allows us to do something like this:

    (() => {
        var count = 0;
    
        for (let i = 0; i < 2; ++i) {
            for (let i = 0; i < 2; ++i) {
                for (let i = 0; i < 2; ++i) {
                    console.log(count++);
                }
            }
        }
    })();
    

    Which results in counting [0, 7].

    Whereas

    (() => {
        var count = 0;
    
        for (var i = 0; i < 2; ++i) {
            for (var i = 0; i < 2; ++i) {
                for (var i = 0; i < 2; ++i) {
                    console.log(count++);
                }
            }
        }
    })();
    

    Only counts [0, 1].

    点赞 评论
  • csdnceshi65
    larry*wei 2016-07-21 17:42

    Some hacks with let:

    1.

        let statistics = [16, 170, 10];
        let [age, height, grade] = statistics;
    
        console.log(height)
    

    2.

        let x = 120,
        y = 12;
        [x, y] = [y, x];
        console.log(`x: ${x} y: ${y}`);
    

    3.

        let node = {
                       type: "Identifier",
                       name: "foo"
                   };
    
        let { type, name, value } = node;
    
        console.log(type);      // "Identifier"
        console.log(name);      // "foo"
        console.log(value);     // undefined
    
        let node = {
            type: "Identifier"
        };
    
        let { type: localType, name: localName = "bar" } = node;
    
        console.log(localType);     // "Identifier"
        console.log(localName);     // "bar"
    

    Getter and setter with let:

    let jar = {
        numberOfCookies: 10,
        get cookies() {
            return this.numberOfCookies;
        },
        set cookies(value) {
            this.numberOfCookies = value;
        }
    };
    
    console.log(jar.cookies)
    jar.cookies = 7;
    
    console.log(jar.cookies)
    
    点赞 评论
  • weixin_41568184
    叼花硬汉 2016-10-14 05:01

    If I read the specs right then let thankfully can also be leveraged to avoid self invoking functions used to simulate private only members - a popular design pattern that decreases code readability, complicates debugging, that adds no real code protection or other benefit - except maybe satisfying someone's desire for semantics, so stop using it. /rant

    var SomeConstructor;
    
    {
        let privateScope = {};
    
        SomeConstructor = function SomeConstructor () {
            this.someProperty = "foo";
            privateScope.hiddenProperty = "bar";
        }
    
        SomeConstructor.prototype.showPublic = function () {
            console.log(this.someProperty); // foo
        }
    
        SomeConstructor.prototype.showPrivate = function () {
            console.log(privateScope.hiddenProperty); // bar
        }
    
    }
    
    var myInstance = new SomeConstructor();
    
    myInstance.showPublic();
    myInstance.showPrivate();
    
    console.log(privateScope.hiddenProperty); // error
    

    See 'Emulating private interfaces'

    点赞 评论
  • csdnceshi51
    旧行李 2016-11-23 22:52

    let

    Block scope

    Variables declared using the let keyword are block-scoped, which means that they are available only in the block in which they were declared.

    At the top level (outside of a function)

    At the top level, variables declared using let don't create properties on the global object.

    var globalVariable = 42;
    let blockScopedVariable = 43;
    
    console.log(globalVariable); // 42
    console.log(blockScopedVariable); // 43
    
    console.log(this.globalVariable); // 42
    console.log(this.blockScopedVariable); // undefined
    

    Inside a function

    Inside a function (but outside of a block), let has the same scope as var.

    (() => {
      var functionScopedVariable = 42;
      let blockScopedVariable = 43;
    
      console.log(functionScopedVariable); // 42
      console.log(blockScopedVariable); // 43
    })();
    
    console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
    console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
    

    Inside a block

    Variables declared using let inside a block can't be accessed outside that block.

    {
      var globalVariable = 42;
      let blockScopedVariable = 43;
      console.log(globalVariable); // 42
      console.log(blockScopedVariable); // 43
    }
    
    console.log(globalVariable); // 42
    console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
    

    Inside a loop

    Variables declared with let in loops can be referenced only inside that loop.

    for (var i = 0; i < 3; i++) {
      var j = i * 2;
    }
    console.log(i); // 3
    console.log(j); // 4
    
    for (let k = 0; k < 3; k++) {
      let l = k * 2;
    }
    console.log(typeof k); // undefined
    console.log(typeof l); // undefined
    // Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
    

    Loops with closures

    If you use let instead of var in a loop, with each iteration you get a new variable. That means that you can safely use a closure inside a loop.

    // Logs 3 thrice, not what we meant.
    for (var i = 0; i < 3; i++) {
      setTimeout(() => console.log(i), 0);
    }
    
    // Logs 0, 1 and 2, as expected.
    for (let j = 0; j < 3; j++) {
      setTimeout(() => console.log(j), 0);
    }
    

    Temporal dead zone

    Because of the temporal dead zone, variables declared using let can't be accessed before they are declared. Attempting to do so throws an error.

    console.log(noTDZ); // undefined
    var noTDZ = 43;
    console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
    let hasTDZ = 42;
    

    No re-declaring

    You can't declare the same variable multiple times using let. You also can't declare a variable using let with the same identifier as another variable which was declared using var.

    var a;
    var a; // Works fine.
    
    let b;
    let b; // SyntaxError: Identifier 'b' has already been declared
    
    var c;
    let c; // SyntaxError: Identifier 'c' has already been declared
    

    const

    const is quite similar to let—it's block-scoped and has TDZ. There are, however, two things which are different.

    No re-assigning

    Variable declared using const can't be re-assigned.

    const a = 42;
    a = 43; // TypeError: Assignment to constant variable.
    

    Note that it doesn't mean that the value is immutable. Its properties still can be changed.

    const obj = {};
    obj.a = 42;
    console.log(obj.a); // 42
    

    If you want to have an immutable object, you should use Object.freeze().

    Initializer is required

    You always must specify a value when declaring a variable using const.

    const a; // SyntaxError: Missing initializer in const declaration
    
    点赞 评论
  • csdnceshi53
    Lotus@ 2016-12-27 09:44

    This article clearly defines the difference between var, let and const

    const is a signal that the identifier won’t be reassigned.

    let, is a signal that the variable may be reassigned, such as a counter in a loop, or a value swap in an algorithm. It also signals that the variable will be used only in the block it’s defined in, which is not always the entire containing function.

    var is now the weakest signal available when you define a variable in JavaScript. The variable may or may not be reassigned, and the variable may or may not be used for an entire function, or just for the purpose of a block or loop.

    https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b

    点赞 评论
  • csdnceshi72
    谁还没个明天 2017-03-22 14:39

    The main difference is the scope difference, while let can be only available inside the scope it's declared, like in for loop, var can be accessed outside the loop for example. From the documentation in MDN (examples also from MDN):

    let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.

    Variables declared by let have as their scope the block in which they are defined, as well as in any contained sub-blocks. In this way, let works very much like var. The main difference is that the scope of a var variable is the entire enclosing function:

    function varTest() {
      var x = 1;
      if (true) {
        var x = 2;  // same variable!
        console.log(x);  // 2
      }
      console.log(x);  // 2
    }
    
    function letTest() {
      let x = 1;
      if (true) {
        let x = 2;  // different variable
        console.log(x);  // 2
      }
      console.log(x);  // 1
    }`
    

    At the top level of programs and functions, let, unlike var, does not create a property on the global object. For example:

    var x = 'global';
    let y = 'global';
    console.log(this.x); // "global"
    console.log(this.y); // undefined
    

    When used inside a block, let limits the variable's scope to that block. Note the difference between var whose scope is inside the function where it is declared.

    var a = 1;
    var b = 2;
    
    if (a === 1) {
      var a = 11; // the scope is global
      let b = 22; // the scope is inside the if-block
    
      console.log(a);  // 11
      console.log(b);  // 22
    } 
    
    console.log(a); // 11
    console.log(b); // 2
    

    Also don't forget it's ECMA6 feature, so it's not fully supported yet, so it's better always transpiles it to ECMA5 using Babel etc... for more info about visit babel website

    点赞 评论
  • weixin_41568183
    零零乙 2017-05-22 01:09

    The difference is in the scope of the variables declared with each.

    In practice, there are a number of useful consequences of the difference in scope:

    1. let variables are only visible in their nearest enclosing block ({ ... }).
    2. let variables are only usable in lines of code that occur after the variable is declared (even though they are hoisted!).
    3. let variables may not be redeclared by a subsequent var or let.
    4. Global let variables are not added to the global window object.
    5. let variables are easy to use with closures (they do not cause race conditions).

    The restrictions imposed by let reduce the visibility of the variables and increase the likelihood that unexpected name collisions will be found early. This makes it easier to track and reason about variables, including their reachability(helping with reclaiming unused memory).

    Consequently, let variables are less likely to cause problems when used in large programs or when independently-developed frameworks are combined in new and unexpected ways.

    var may still be useful if you are sure you want the single-binding effect when using a closure in a loop (#5) or for declaring externally-visible global variables in your code (#4). Use of var for exports may be supplanted if export migrates out of transpiler space and into the core language.

    Examples

    1. No use outside nearest enclosing block: This block of code will throw a reference error because the second use of x occurs outside of the block where it is declared with let:

    {
        let x = 1;
    }
    console.log(`x is ${x}`);  // ReferenceError during parsing: "x is not defined".
    

    In contrast, the same example with var works.

    2. No use before declaration:
    This block of code will throw a ReferenceError before the code can be run because x is used before it is declared:

    {
        x = x + 1;  // ReferenceError during parsing: "x is not defined".
        let x;
        console.log(`x is ${x}`);  // Never runs.
    }
    

    In contrast, the same example with var parses and runs without throwing any exceptions.

    3. No redeclaration: The following code demonstrates that a variable declared with let may not be redeclared later:

    let x = 1;
    let x = 2;  // SyntaxError: Identifier 'x' has already been declared
    

    4. Globals not attached to window:

    var button = "I cause accidents because my name is too common.";
    let link = "Though my name is common, I am harder to access from other JS files.";
    console.log(link);  // OK
    console.log(window.link);  // undefined (GOOD!)
    console.log(window.button);  // OK
    

    5. Easy use with closures: Variables declared with var do not work well with closures inside loops. Here is a simple loop that outputs the sequence of values that the variable i has at different points in time:

    for (let i = 0; i < 5; i++) {
        console.log(`i is ${i}`), 125/*ms*/);
    }
    

    Specifically, this outputs:

    i is 0
    i is 1
    i is 2
    i is 3
    i is 4
    

    In JavaScript we often use variables at a significantly later time than when they are created. When we demonstrate this by delaying the output with a closure passed to setTimeout:

    for (let i = 0; i < 5; i++) {
        setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
    }
    

    ... the output remains unchanged as long as we stick with let. In contrast, if we had used var i instead:

    for (var i = 0; i < 5; i++) {
        setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
    }
    

    ... the loop unexpectedly outputs "i is 5" five times:

    i is 5
    i is 5
    i is 5
    i is 5
    i is 5
    
    点赞 评论
  • csdnceshi75
    衫裤跑路 2017-10-28 12:42

    var is global scope (hoist-able) variable.

    let and const is block scope.

    test.js

    {
        let l = 'let';
        const c = 'const';
        var v = 'var';
        v2 = 'var 2';
    }
    
    console.log(v, this.v);
    console.log(v2, this.v2);
    console.log(l); // ReferenceError: l is not defined
    console.log(c); // ReferenceError: c is not defined

    </div>
    
    点赞 评论
  • csdnceshi59
    ℙℕℤℝ 2017-12-17 10:47

    let is a part of es6. These functions will explain the difference in easy way.

    function varTest() {
      var x = 1;
      if (true) {
        var x = 2;  // same variable!
        console.log(x);  // 2
      }
      console.log(x);  // 2
    }
    
    function letTest() {
      let x = 1;
      if (true) {
        let x = 2;  // different variable
        console.log(x);  // 2
      }
      console.log(x);  // 1
    }
    
    点赞 评论
  • csdnceshi50
    三生石@ 2018-05-18 07:27

    Check this link in MDN

    let x = 1;
    
    if (x === 1) {
    let x = 2;
    
    console.log(x);
    // expected output: 2
    }
    
    console.log(x);
    // expected output: 1
    
    点赞 评论
  • weixin_41568110
    七度&光 2018-05-22 13:12

    When Using let

    The let keyword attaches the variable declaration to the scope of whatever block (commonly a { .. } pair) it's contained in. In other words,let implicitly hijacks any block's scope for its variable declaration.

    let variables cannot be accessed in the window object because they cannot be globally accessed.

    function a(){
        { // this is the Max Scope for let variable
            let x = 12;
        }
        console.log(x);
    }
    a(); // Uncaught ReferenceError: x is not defined
    

    When Using var

    var and variables in ES5 has scopes in functions meaning the variables are valid within the function and not outside the function itself.

    var variables can be accessed in the window object because they cannot be globally accessed.

    function a(){ // this is the Max Scope for var variable
        { 
            var x = 12;
        }
        console.log(x);
    }
    a(); // 12
    

    If you want to know more continue reading below

    one of the most famous interview questions on scope also can suffice the exact use of let and var as below;

    When using let

    for (let i = 0; i < 10 ; i++) {
        setTimeout(
            function a() {
                console.log(i); //print 0 to 9, that is literally AWW!!!
            }, 
            100 * i);
    }
    

    This is because when using let, for every loop iteration the variable is scoped and has its own copy.

    When using var

    for (var i = 0; i < 10 ; i++) {
        setTimeout(
            function a() {
                console.log(i); //print 10 times 10
            }, 
            100 * i);
    }
    

    This is because when using var, for every loop iteration the variable is scoped and has shared copy.

    点赞 评论
  • weixin_41568196
    撒拉嘿哟木头 2018-08-07 10:25

    As mentioned above:

    The difference is scoping. var is scoped to the nearest function block and let is scoped to the nearest enclosing block, which can be smaller than a function block. Both are global if outside any block.Lets see an example:

    Example1:

    In my both examples I have a function myfunc. myfunc contains a variable myvar equals to 10. In my first example I check if myvar equals to 10 (myvar==10) . If yes, I agian declare a variable myvar (now I have two myvar variables)using var keyword and assign it a new value (20). In next line I print its value on my console. After the conditional block I again print the value of myvar on my console. If you look at the output of myfunc, myvar has value equals to 20.

    let keyword

    Example2: In my second example instead of using var keyword in my conditional block I declare myvar using let keyword . Now when I call myfunc I get two different outputs: myvar=20 and myvar=10.

    So the difference is very simple i.e its scope.

    点赞 评论
  • csdnceshi67
    bug^君 2018-09-09 13:08

    Function VS block scope:

    The main difference between var and let is that variables declared with var are function scoped. Whereas functions declared with let are block scoped. For example:

    function testVar () {
      if(true) {
        var foo = 'foo';
      }
    
      console.log(foo);
    }
    
    testVar();  
    // logs 'foo'
    
    
    function testLet () {
      if(true) {
        let bar = 'bar';
      }
    
      console.log(bar);
    }
    
    testLet(); 
    // reference error
    // bar is scoped to the block of the if statement 
    

    variables with var:

    When the first function testVar gets called the variable foo, declared with var, is still accessible outside the if statement. This variable foo would be available everywhere within the scope of the testVar function.

    variables with let:

    When the second function testLet gets called the variable bar, declared with let, is only accessible inside the if statement. Because variables declared with let are block scoped (where a block is the code between curly brackets e.g if{} , for{}, function{}).

    let variables don't get hoisted:

    Another difference between var and let is variables with declared with let don't get hoisted. An example is the best way to illustrate this behavior:

    variables with let don't get hoisted:

    console.log(letVar);
    
    let letVar = 10;
    // referenceError, the variable doesn't get hoisted
    

    variables with var do get hoisted:

    console.log(varVar);
    
    var varVar = 10;
    // logs undefined, the variable gets hoisted
    

    Global let doesn't get attached to window:

    A variable declared with let in the global scope (which is code that is not in a function) doesn't get added as a property on the global window object. For example (this code is in global scope):

    var bar = 5;
    let foo  = 10;
    
    console.log(bar); // logs 5
    console.log(foo); // logs 10
    
    console.log(window.bar);  
    // logs 5, variable added to window object
    
    console.log(window.foo);
    // logs undefined, variable not added to window object
    


    When should let be used over var?

    Use let over var whenever you can because it is simply scoped more specific. This reduces potential naming conflicts which can occur when dealing with a large number of variables. var can be used when you want a global variable explicitly to be on the window object (always consider carefully if this is really necessary).

    点赞 评论

相关推荐