Javascript 什么';“使用”的区别是什么;让我们;及;var";? 介绍了ECMAScript 6。

Javascript 什么';“使用”的区别是什么;让我们;及;var";? 介绍了ECMAScript 6。,javascript,scope,ecmascript-6,var,let,Javascript,Scope,Ecmascript 6,Var,Let,我听说它被描述为一个local变量,但我仍然不确定它的行为与var关键字有什么不同 有什么区别?。什么时候应该使用而不是var?下面是一个例子 let的工作原理非常类似于var。主要区别在于var变量的范围是整个封闭函数 维基百科上显示了哪些浏览器支持Javascript 1.7 请注意,只有Mozilla和Chrome浏览器支持它。IE、Safari和其他可能不这样做的人。下面是一个例子 let的工作原理非常类似于var。主要区别在于var变量的范围是整个封闭函数 维基百科上显示了哪些浏览器支

我听说它被描述为一个
local
变量,但我仍然不确定它的行为与
var
关键字有什么不同

有什么区别?。什么时候应该使用
而不是
var

下面是一个例子

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

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

请注意,只有Mozilla和Chrome浏览器支持它。IE、Safari和其他可能不这样做的人。

下面是一个例子

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

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


请注意,只有Mozilla和Chrome浏览器支持它。IE、Safari和其他可能不这样做。

有一些细微的区别-
让范围界定的行为更像其他语言中变量范围界定的行为

e、 它的作用域是封闭块,它们在声明之前不存在,等等


但是值得注意的是,
let
只是较新的Javascript实现的一部分,并且具有不同程度的可用性。

有一些细微的区别-
let
作用域的行为与其他语言中的变量作用域行为类似

e、 它的作用域是封闭块,它们在声明之前不存在,等等

但是值得注意的是,
let
只是较新的Javascript实现的一部分,并且具有不同程度的作用域规则 主要区别在于范围规则。由
var
关键字声明的变量的作用域是直接函数体(因此是函数作用域),而
let
变量的作用域是由
{}
表示的直接封闭块(因此是块作用域)

let
关键字引入语言的原因是函数范围令人困惑,是JavaScript中错误的主要来源之一

请从以下方面查看此示例:

let
在对变量定义求值之前,不初始化变量。在初始化之前访问它们会导致
ReferenceError
。从块的开始到初始化被处理,变量被称为处于“时间死区”

function checkHoisting() {
  console.log(foo); // ReferenceError
  let foo = "Foo";
  console.log(foo); // Foo
}

checkHoisting();
创建全局对象属性 与
var
不同,在顶层,
let
不在全局对象上创建属性:

var foo = "Foo";  // globally scoped
let bar = "Bar"; // not allowed to be globally scoped

console.log(window.foo); // Foo
console.log(window.bar); // undefined
重声明 在严格模式下,
var
将允许您在同一范围内重新声明同一变量,而
let
将引发语法错误

'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.

let bar = "bar1"; 
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
范围界定规则 主要区别在于范围规则。由
var
关键字声明的变量的作用域是直接函数体(因此是函数作用域),而
let
变量的作用域是由
{}
表示的直接封闭块(因此是块作用域)

let
关键字引入语言的原因是函数范围令人困惑,是JavaScript中错误的主要来源之一

请从以下方面查看此示例:

let
在对变量定义求值之前,不初始化变量。在初始化之前访问它们会导致
ReferenceError
。从块的开始到初始化被处理,变量被称为处于“时间死区”

function checkHoisting() {
  console.log(foo); // ReferenceError
  let foo = "Foo";
  console.log(foo); // Foo
}

checkHoisting();
创建全局对象属性 与
var
不同,在顶层,
let
不在全局对象上创建属性:

var foo = "Foo";  // globally scoped
let bar = "Bar"; // not allowed to be globally scoped

console.log(window.foo); // Foo
console.log(window.bar); // undefined
重声明 在严格模式下,
var
将允许您在同一范围内重新声明同一变量,而
let
将引发语法错误

'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.

let bar = "bar1"; 
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared

这里有一个例子来补充其他人已经写过的内容。假设您要创建一个函数数组,
adderFunctions
,其中每个函数接受一个数字参数,并返回参数和数组中函数索引的总和。尝试使用
var
关键字通过循环生成
adderFunctions
,不会像人们天真地期望的那样工作:

// 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
这次,
i
for
循环的每次迭代中都会反弹。现在,每个函数在创建函数时保留
i
的值,并且
adderFunctions
的行为与预期一致

现在,想象一下混合这两种行为,您可能会看到为什么不建议在同一脚本中混合较新的
let
const
与较旧的
var
。这样做可能会导致一些令人困惑的代码

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
constdoubleadderfunctions=[];
对于(变量i=0;i<1000;i++){
常数j=i;
双加法器函数[i]=x=>x+i+j;
}
const add18=双加法器函数[9];
const add24=双加法器函数[12];
//调试这样的情况并不有趣,尤其是当
//代码比本例中的代码更复杂。
console.log(add18(24)==42);//=>假的
console.log(add24(18)==42);//=>假的
console.log(add18(24)==add24(18));//=>假的
console.log(add18(24)==2018);//=>假的
console.log(add24(18)==2018);//=>假的
console.log(add18(24)==1033);//=>真的
console.log(add24(18)==1030);//=>真的
别让这种事发生在你身上。使用短绒

注意:这是一个教学示例,旨在演示
var
/
let
在循环中的行为以及易于理解的函数闭包。这将是一种可怕的数字相加方式。但是在匿名函数clos中捕获数据的一般技术
{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined
var x = 1;
var x = 2;
let x = 1;
let x = 2;
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
}
{
   console.log(cc); // undefined. Caused by hoisting
   var cc = 23;
}

{
   console.log(bb); // ReferenceError: bb is not defined
   let bb = 23;
}
function process(data) {
    //...
}

var hugeData = { .. };

process(hugeData);

var btn = document.getElementById("mybutton");
btn.addEventListener( "click", function click(evt){
    //....
});
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){
    //....
});
// print '5' 5 times
for (var i = 0; i < 5; ++i) {
    setTimeout(function () {
        console.log(i);
    }, 1000);  
}
// print 1, 2, 3, 4, 5. now
for (let i = 0; i < 5; ++i) {
    setTimeout(function () {
        console.log(i);
    }, 1000);  
}
// 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
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
}
(() => {
    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++);
            }
        }
    }
})();
(() => {
    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++);
            }
        }
    }
})();
    let statistics = [16, 170, 10];
    let [age, height, grade] = statistics;

    console.log(height)
    let x = 120,
    y = 12;
    [x, y] = [y, x];
    console.log(`x: ${x} y: ${y}`);
    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"
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)
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
var globalVariable = 42;
let blockScopedVariable = 43;

console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43

console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
(() => {
  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
{
  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
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.
// 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);
}
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
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 a = 42;
a = 43; // TypeError: Assignment to constant variable.
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
const a; // SyntaxError: Missing initializer in const declaration
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
}`
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
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
{
    let x = 1;
}
console.log(`x is ${x}`);  // ReferenceError during parsing: "x is not defined".
{
    x = x + 1;  // ReferenceError during parsing: "x is not defined".
    let x;
    console.log(`x is ${x}`);  // Never runs.
}
let x = 1;
let x = 2;  // SyntaxError: Identifier 'x' has already been declared
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
for (let i = 0; i < 5; i++) {
    console.log(`i is ${i}`), 125/*ms*/);
}
i is 0
i is 1
i is 2
i is 3
i is 4
for (let i = 0; i < 5; i++) {
    setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
for (var i = 0; i < 5; i++) {
    setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
i is 5
i is 5
i is 5
i is 5
i is 5
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
}
function a(){
    { // this is the Max Scope for let variable
        let x = 12;
    }
    console.log(x);
}
a(); // Uncaught ReferenceError: x is not defined
function a(){ // this is the Max Scope for var variable
    { 
        var x = 12;
    }
    console.log(x);
}
a(); // 12
for (let i = 0; i < 10 ; i++) {
    setTimeout(
        function a() {
            console.log(i); //print 0 to 9, that is literally AWW!!!
        }, 
        100 * i);
}
for (var i = 0; i < 10 ; i++) {
    setTimeout(
        function a() {
            console.log(i); //print 10 times 10
        }, 
        100 * i);
}
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 
console.log(letVar);

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

var varVar = 10;
// logs undefined, the variable gets hoisted
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
(function timer() {
    for(var i = 0; i <= 5; i++) {
        setTimeout(function notime() { console.log(i); }, i * 1000);
    }
})();


   Stack            VariableEnvironment //one VariablEnvironment for timer();
                                       // when the timer is out - the value will be the same value for each call
5. [setTimeout, i]  [i=5] 
4. [setTimeout, i]  
3. [setTimeout, i]
2. [setTimeout, i]
1. [setTimeout, i]
0. [setTimeout, i]

####################    

(function timer() {
    for (let i = 0; i <= 5; i++) {
        setTimeout(function notime() { console.log(i); }, i * 1000);
    }
})();

   Stack           LexicalEnvironment - each iteration has a new lexical environment
5. [setTimeout, i]  [i=5]       
                      LexicalEnvironment 
4. [setTimeout, i]    [i=4]     
                        LexicalEnvironment 
3. [setTimeout, i]      [i=3]       
                         LexicalEnvironment 
2. [setTimeout, i]       [i=2]
                           LexicalEnvironment 
1. [setTimeout, i]         [i=1]
                             LexicalEnvironment 
0. [setTimeout, i]           [i=0]
function test() {
    for(var z = 0; z < 69; z++) {
        //todo
    }
    //z is visible outside the loop
}
function test() {
    for(let z = 0; z < 69; z++) {
        //todo
    }
    //z is not defined :(
}
var cat = "cat";
let dog = "dog";

var animals = () => {
    var giraffe = "giraffe";
    let lion = "lion";

    console.log(cat);  //will print 'cat'.
    console.log(dog);  //will print 'dog', because dog was declared outside this function (like var cat).

    console.log(giraffe); //will print 'giraffe'.
    console.log(lion); //will print 'lion', as lion is within scope.
}

console.log(giraffe); //will print 'giraffe', as giraffe is a global variable (var).
console.log(lion); //will print UNDEFINED, as lion is a 'let' variable and is now out of scope.
let gfoo = 123;
if (true) {
    let gfoo = 456;
}
console.log(gfoo); // 123

var hfoo = 123;
if (true) {
    var hfoo = 456;
}
console.log(hfoo); // 456
for (let i = 0; i < 5; i++) {
  // i accessible ✔️
}
// i not accessible ❌
for (var i = 0; i < 5; i++) {
  // i accessible ✔️
}
// i accessible ✔️
let variableName = 'a';
eval("let " + variableName + '= 10;');
console.log(a);   // this doesn't work
var variableName = 'a';
eval("var " + variableName + '= 10;');
console.log(a);   // this works