使用“ let”和“ var”有什么区别?

ECMAScript 6引入了该let声明

我听说它被描述为“局部”变量,但是我仍然不太确定它的行为与var关键字的不同

有什么区别?什么时候应该let用完var

小卤蛋Green小哥2020/03/09 12:35:55

在此处输入图片说明

看一下这张图片,我创建了一个非常简单的示例来演示constlet变量。如您所见,当您尝试更改const变量时,会出现错误(尝试覆盖常量的“名称”),但请看一下let变量...

首先声明let age = 33,然后分配其他值age = 34;,这是可以的,尝试更改let变量时没有任何错误。

LEY小卤蛋2020/03/09 12:35:55

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.

让关键字

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.

宝儿猿2020/03/09 12:35:55

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

宝儿猿2020/03/09 12:35:55

现在,我认为使用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
}

我认为人们以后将开始在这里使用let,以便他们在JavaScript中具有与其他语言,Java,C#等类似的作用域。

对JavaScript的作用域了解不清的人过去常常会犯错误。

不支持使用进行吊装let

通过这种方法,可以消除JavaScript中存在的错误。

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

泡芙梅2020/03/09 12:35:55

我认为术语和大多数示例有点让人不知所措。我个人与之不同的主要问题是了解什么是“阻止”。在某种程度上,我意识到,一个块将是除IF声明以外的任何花括号{函数或循环的左括号将定义一个新块,其中定义的任何内容在同一事物(函数或循环)let的右括号后将不可用}考虑到这一点,更容易理解:

let msg = "Hello World";

function doWork() { // msg will be available since it was defined above this opening bracket!
  let friends = 0;
  console.log(msg);

  // with VAR though:
  for (var iCount2 = 0; iCount2 < 5; iCount2++) {} // iCount2 will be available after this closing bracket!
  console.log(iCount2);
  
    for (let iCount1 = 0; iCount1 < 5; iCount1++) {} // iCount1 will not be available behind this closing bracket, it will return undefined
  console.log(iCount1);
  
} // friends will no be available after this closing bracket!
doWork();
console.log(friends);

古一斯丁猴子2020/03/09 12:35:55

我想将这些关键字链接到执行上下文,因为执行上下文在所有这些方面都很重要。执行上下文具有两个阶段:创建阶段和执行阶段。此外,每个执行上下文都具有可变环境和外部环境(其词法环境)。

在执行上下文的创建阶段,var,let和const仍将其变量在给定执行上下文的变量环境中以未定义的值存储在内存中。区别在于执行阶段。如果在分配值之前使用引用使用var定义的变量,则该变量将是未定义的。没有例外。

但是,在声明之前,不能引用用let或const声明的变量。如果尝试在声明它之前使用它,则在执行上下文的执行阶段将引发异常。现在,根据执行上下文的创建阶段,该变量仍将保留在内存中,但是引擎不允许您使用它:

function a(){
    b;
    let b;
}
a();
> Uncaught ReferenceError: b is not defined

使用var定义的变量,如果引擎无法在当前执行上下文的变量环境中找到该变量,则它将向上作用域链(外部环境)并检查该变量的外部环境的变量环境。如果在此处找不到它,它将继续搜索范围链。let和const并非如此。

let的第二个特点是它引入了块作用域。块由花括号定义。示例包括功能块,if块,for块等。当在块内部使用let声明变量时,该变量仅在块内部可用。实际上,每次运行该块时,例如在for循环内,它将在内存中创建一个新变量。

ES6还引入了const关键字来声明变量。const也是块作用域的。let和const之间的区别在于,必须使用初始化程序声明const变量,否则它将产生错误。

最后,当涉及执行上下文时,使用var定义的变量将附加到“ this”对象。在全局执行上下文中,它将是浏览器中的窗口对象。let或const并非如此。

A十三2020/03/09 12:35:55

let是es6的一部分。这些功能将以简单的方式说明差异。

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
}
猪猪理查德2020/03/09 12:35:55

一些技巧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和setter方法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)
HarryGil2020/03/09 12:35:55

如果我没看错规范,那么let 值得庆幸的是,还可以利用它来避免用于模拟仅私有成员的自调用函数 - 一种流行的设计模式,它降低了代码的可读性,使调试复杂化,没有增加任何实际的代码保护或其他好处-除了可能使某人满意之外对语义的渴望,所以停止使用它。/ 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

请参阅“ 模拟专用接口

十三古一神奇2020/03/09 12:35:55

使用时 let

let关键字附加的变量声明到任何块(通常是范围{ .. }它包含在对)。换句话说,let隐含劫持块的其变量声明范围。

let无法在window对象中访问变量,因为无法全局访问它们。

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

使用时 var

var ES5中的变量具有函数作用域,这意味着变量在函数内部有效,而在函数本身外部无效。

var变量可以在window对象中访问,因为它们不能全局访问。

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

如果您想了解更多,请继续阅读下面的内容

对范围最有名的面试问题,人们也可以足够精确的使用letvar如下;

使用时 let

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

这是因为使用时let,对于每次循环迭代,变量都具有作用域并具有自己的副本。

使用时 var

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

这是因为使用时var,对于每次循环迭代,变量都具有作用域并具有共享副本。

樱猪猪2020/03/09 12:35:55

看起来,至少在Visual Studio 2015 TypeScript 1.5中,“ var”允许在块中使用多个相同变量名的声明,而“ let”则不允许。

这不会产生编译错误:

var x = 1;
var x = 2;

这将:

let x = 1;
let x = 2;
Davaid神奇Eva2020/03/09 12:35:55

let 很有趣,因为它允许我们执行以下操作:

(() => {
    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++);
            }
        }
    }
})();

结果计数为[0,7]。

鉴于

(() => {
    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++);
            }
        }
    }
})();

仅计数[0,1]。

Green前端2020/03/09 12:35:55

可能以下两个功能显示出差异:

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
}
路易番长2020/03/09 12:35:54

有一些细微的差异- let作用域的行为更像变量作用域在或多或少的其他语言中所做的。

例如,它的作用域为封闭的块,它们在声明之前不存在,等等。

但是,值得注意的是,这let只是较新的Javascript实现的一部分,并且具有不同程度的浏览器支持

GreenMandy2020/03/09 12:35:54

Here is an example for the difference between the two (support just started for chrome):
在此处输入图片说明

如您所见,var j变量仍然具有for循环范围(Block Scope)之外的值,但let i变量在for循环范围之外未定义。

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

小小小胖2020/03/09 12:35:54

可接受的答案遗漏了一点:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined
Cathy2020/03/09 12:35:54

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.

for(var i=1; i<6; i++) {
  $("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p> 
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>

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.

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

(Tested in Chrome and Firefox 50)

for(let i=1; i<6; i++) {
  $("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p> 
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>

OU2020/03/09 12:35:54

下面是一个在解释let的关键字一些例子。

let工作非常像var主要区别在于var变量的范围是整个封闭函数

维基百科上的此表显示了哪些浏览器支持Javascript 1.7。

请注意,只有Mozilla和Chrome浏览器支持它。IE,Safari和其他可能没有的。