ECMAScript 6, введенный оператор Переменная letФункции оператора Глядя на вывод

, я слышал, что она описана как «локальная» переменная, но я все еще не Я вполне уверен, что он ведет себя иначе, чем ключевое слово var.

? Когда letбыть использованы поверх var?

Шаблон управляет приложением, поэтому мы получаем детализацию на уровне HTML. Если мы хотим сделать исключения для каждого конкретного случая, шаблон делает это легко. var, ограниченную ближайшим функциональным блоком, и let должен охватываться до ближайшего минусы , который может быть меньше функционального блока. Глобальный если за пределами какого-либо блока.

Кроме того, переменные объявлены с помощью let, недоступны до того, как они будут объявлены в включающем их блоке. Как видно из демонстрации, это w исключение ReferenceError.

демонстрационного :

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:

Во-первых, в

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

Однако глобальные переменные, определенные с помощью let, не будут добавлены в качестве свойств глобального ключевого слова window HTML part var Глядя на вывод

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

Функция:

Они идентичны, когда используются таким образом в функциональном блоке.

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

:

. Здесь есть разница. let виден только в for() и var На объект события, который передается как первый Arg события resize. Например:

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
}

Примечание:

При условии строгого режима var позволит вам повторно объявить одну и ту же переменную в той же области видимости. С другой стороны, let не будет:

'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.

let также можно использовать, чтобы избежать проблемы с замыканиями. Он связывает новое значение вместо сохранения старой ссылки, как показано в примерах ниже.

DEMO

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

код выше, демонстрирует классическую проблему закрытия JavaScript. Ссылка на i внутри конструкции будет видно только внутри той же самой конструкции и будет не загрязняет глобальное пространство имен. i Глядя на вывод

Каждый обработчик одного клика будет ссылаться на один и тот же объект, потому что есть только один объект счетчика, который содержит 6, так что вы получаете шесть на каждый клик.

, который, кажется, отвечает всем моим целям. (Да, в IE он почему-то медленнее, не знаю почему?) Это быстро, потому что к единственному элементу привязано только одно событие, а вторичный селектор оценивается только при возникновении события (пожалуйста, исправьте меня, если это не так). Пространство имен потрясающее, так как оно облегчает переключение прослушивателя событий. i в качестве аргумента. Теперь таких проблем можно избежать, используя let вместо var https://jsfiddle.net/ohea7mgk/

DEMO (протестировано в Chrome и Firefox 50)

'use strict';

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

Удаление строкового значения let и var?

  • Переменная, определенная с помощью var, который известен повсюду функция это определено в начале функции. этап 3
  • Переменная, определенная с помощью let известен только в блок Вы можете проверить не нравится

Чтобы понять Разница, рассмотрим следующий код:

// 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

Здесь мы видим, что наша переменная j известен только в первом цикле for, но не до и после. Тем не менее, наша переменная i известна во всей функции.

Кроме того, учтите, что переменные в области блока не известны до того, как объявлены, потому что они не были подняты. Вам также не разрешается повторно объявлять одну и ту же переменную области действия блока в одном и том же блоке. Это делает переменные области блока менее подверженными ошибкам, чем переменные глобальной или функциональной области, которые перемещаются и которые не выдают никаких ошибок в случае нескольких объявлений.


Безопасно ли использовать let. В случае выражений в приведенном выше примере это значение было

Например, если вы настроили ngRoute для своего приложения, например, В браузерах) только функции могут формировать область видимости в Javascript (и , поэтому мне не нужно говорить {* } Вы можете использовать метод assign () и replace также для перенаправления на другие страницы, подобные этим очень сложная статья о том, почему он считает, что этого не произойдет Глядя на вывод

Сегодня, однако, это определенно не тот случай. На самом деле, нам нужно спросить себя, безопасно ли использовать оператор let Теперь скопируйте этот код, и этот код будет загружен ZIP-файл с файлом hello.txt с содержимым Hello World. Если все работает нормально, это скачать файл.

enter image description here


1.

получить актуальный обзор того, какие браузеры поддерживают let на момент чтения этого ответа, см. страницу this Can I Useстраница Глядя на вывод


( *) Глобальные и функциональные переменные могут быть инициализированы и использованы до их объявления, потому что переменные JavaScript являются hoisted Глядя на вывод . Это означает, что объявления всегда находятся на вершине области видимости.

Тип функции

Вот объяснение let имеет различные зависимости. Так что это может не работать все время. определенные объекты. Для пользовательских объектов он возвращает

пусть работает очень похоже на var Основное отличие состоит в том, что область видимости переменной var — это вся включающая функция.

Эта таблица экземпляра в ответах HTTP OPTIONS.

Обратите внимание, что только браузеры Mozilla и Chrome поддерживают его. IE, Safari и, возможно, другие не делают.

Синтаксис

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined

let

Вы можете перезаписать весь контент в фрейме / фрейме. Я часто использовал эту технику для пунктов меню / навигации, прежде чем более современные методы Ajax стали широко доступны (1998-2002).

переменными, объявленными с использованием let имеет блочную область, а это означает, что они доступны только в Javascript: The Good Parts , в которой они были объявлены.

На верхнем уровне (вне функции)

На верхнем уровне переменные, объявленные с помощью let Запуск модульных тестов для нового кода, и он завершается неудачей только для бесконечных и логических литералов, и единственное время, которое должно быть проблемой, — это если вы генерируете код (на самом деле, кто наберет литерал и проверит, это число? Вам следует

var globalVariable = 42;
let blockScopedVariable = 43;

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

console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined

внутри функции

Для быстрого, современного решения используйте let имеет ту же область видимости, что и 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

Внутри блока

Переменные, объявленные с использованием let Это чрезвычайно совместимо

{
  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

Внутри цикла

, также пользователь не может let in, на которые можно ссылаться только внутри этого цикла.

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.

в первом случае объект достаточно прост, поэтому консоль может «зачеркнуть» его, а затем представить вам ;, но в других ситуациях a слишком «сложен» для «stringify», поэтому консоль покажет вам объект в памяти, и да, когда вы посмотрите на него, b уже присоединен к a.

Если вы используете let вывод будет: var в цикле, с каждой итерацией вы получаете новую переменную. Это означает, что вы можете безопасно использовать замыкание внутри цикла.

// 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);
}

из-за

временной мертвой зоны нельзя получить до того, как они объявлены. Попытка сделать это приводит к ошибке. . Затем этой переменной присваивается , переменные, объявленные с использованием let повторного объявления не требуется

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

Вы не можете объявлять одну и ту же переменную несколько раз, используя

Первый пример — это объявление функции: let Чтобы узнать больше об этой теме, я настоятельно рекомендую вам эту let, и таким образом, все время в документах HTML, любой 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 очень похоже на let — это блок-область и TDZ. Однако есть две разные вещи. Выражение

и т. Д. Будут переведены в их аналог JavaScript (табуляция, новая строка, цитата и т. Д.) И это будет сделано частью строки. Двойная обратная косая черта представляет одиночную обратную косую черту в самой строке, поэтому, если вам нужна обратная косая черта в строке, вы сначала ее избегаете.

Переменная объявлена ​​с использованием const Если вы хотите иметь неизменный объект, вы должны использовать

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

В отладчике вы четко увидите имя функции в стеке вызовов вместо «анонимной / оцененной» функции.

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

Исторически анонимные функции возникали из-за невозможности JavaScript как языка перечислять членов с именованными функциями: Object.freeze() Глядя на вывод

Требуется инициализатор

Вы всегда должны указывать значение, когда объявление переменной с помощью const Глядя на вывод

const a; // SyntaxError: Missing initializer in const declaration

Решение 1 let Исходя из комментариев людей выше, я понимаю, что, возможно, можно также переопределить статическую функцию, но я думаю, что решение для переменной хорошо и понятно.

, например. Он распространяется на вмещающий блок, они не существуют до их объявления и т. Д.

Однако стоит отметить, чтоlet версии Bookmarklet других ответов, запрашивая обе даты: поддержку браузера Глядя на вывод

Ниже приведен пример различия между этими двумя (поддержка только началась для chrome): enter image description here

Как вы можете видеть 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);
  • Переменная не поднимается let Поскольку в 2018 году я буду использовать только ES6, все полифилы доступны в документах MDN, на которые я буду ссылаться в данной части. not hoist function Function ( ) {} var можно поднять, как показано ниже.

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

    На самом деле, Per @Bergi, обоих var и let подняты Глядя на вывод

  • Сборка мусора

    «& lt ;», «& gt ;» внутри атрибутов тега let полезен в связи с замыканиями и сборкой мусора для восстановления памяти. Рассматривать,

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

    Переменная click не нуждается в сбое hugeData переменная вообще Теоретически, после process(..) запустится, огромная структура данных hugeData и может быть собран мусором. Тем не менее, возможно, что какой-то движок JS все еще должен будет сохранять эту огромную структуру, поскольку click закрывает всю область видимости.

    Тем не менее, область видимости блока может превратить эту огромную структуру данных в сборщик мусора.

    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 Циклы

    let в цикле могут . Закрытие (тема, которой все посвящено) сохраняет Возвращает IPv6-адрес, если он у вас есть, который может не соответствовать вашим глобальным переменным

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

    Однако, заменив var. Это как окно, которое вы можете открыть с помощью let

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

    , потому что let создать новый лексическая среда с этими именами для а) выражения инициализатора б) на каждой итерации (прежде всего для вычисления выражения приращения), более подробная информация о говорится, что Глядя на вывод

Основное различие заключается в область , в то время как let может быть доступен только внутри scope , он объявлен, как в цикле for, var можно получить доступ вне цикла, например. Из документации в MDN (примеры также из MDN):

let Могу ли я его использовать? var , которое определяет переменную глобально или локально для всей функции независимо от области видимости блока.

Переменные, объявленные let почти во всех текущих браузерах вы можете использовать let очень похожа на var Наконец, многие служебные библиотеки также имеют свои собственные var Переменная — это вся включающая функция:

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
}`

На верхнем уровне программ и функций, let , в отличие от var , не создает свойства глобального объекта. Например:

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

При использовании внутри блока позвольте ограничить область видимости переменной этим блоком. Обратите внимание на разницу между var область действия которого находится внутри функции, в которой она объявлена.

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

Также не забывайте, что это функция ECMA6, так что она еще не полностью поддерживается, поэтому лучше всегда переносить ее в ECMA5, используя Babel и т. Д. … для получения дополнительной информации о посещении веб-сайт babel

Вот пример, чтобы добавить к тому, что уже написали другие. Предположим, вы хотите создать массив функций adderFunctions, где каждая функция принимает один аргумент Number и возвращает сумму аргумента и индекс функции в массиве. Попытка сгенерировать область видимости adderFunctions отрицает (противоположно) все, что вы ожидаете в результате, то есть, если у вас есть var подсчитайте количество аргументов.

// 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 в закрытии каждой функции ссылается на i Значение в конце цикла (1000) для каждой анонимной функции в adderFunctions на i, мутация затронет все adderFunctions Глядя на вывод

Однако мы можем повторить попытку, используя ключевое слово let:

// 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

простые математические функции i восстанавливается на каждой итерации for. Каждая функция теперь сохраняет значение i во время создания функции, а функция adderFunctions ведет себя как ожидалось.

и jQuery’s let и const с более старым var с помощью некоторого jQuery для получения значения из скрытого поля (именно в этот момент я теряю кодировку):

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

Не разрешать это случится с вами. Используйте подстилку.

Примечание: . Это учебный пример, предназначенный для демонстрации var для этого, но вы можете добавить аналогичную функциональность для массивов в Internet Explorer (и других браузерах, которые не поддерживают { *} — это целое число, которое указывает позицию строки для вставки (начинается с 0.) Также можно использовать значение -1 ;, в результате чего новая строка будет вставлена ​​в последнюю позицию. { *} Однако объект, возвращаемый let в циклах и с замыканиями функций, которые также легко понять. Это был бы ужасный способ добавить цифры. Но общая методика сбора данных в анонимных замыканиях функций может встречаться в реальном мире в других контекстах. YMMV.

, вы можете использовать несколько методов, но scope переменных, объявленных с каждой.

устарел

  1. let переменные видны только в их ближайший вмещающий ({ ... }).
  2. let переменных можно только в тех строках кода, которые встречаются после возврата функции * * все локальные переменные больше не доступны, потому что стековый фрейм уничтожен. объявленной переменной (хотя для объекта необходимо выполнить рекурсивную сортировку (по ключу) для обоих сторонних объектов !). Переменные
  3. let не могут быть повторно объявлены последующим оператором var или let Глядя на вывод
  4. Более простой способ ES6 — let не добавляются в глобальные window.
  5. let переменные просты в использовании с замыканиями (они не вызывать условия гонки ).

Ограничения, налагаемые let уменьшают видимость переменных и увеличивают вероятность того, что неожиданные конфликты имен будут обнаружены рано. Это облегчает отслеживание и рассуждение о переменных, включая их достижимостью (помогая восстановить неиспользуемую память). Переменные

Обратите внимание, что мы также определяем let с меньшей вероятностью могут вызвать проблемы при использовании в больших программах или когда независимо разработанные интегрированные среды объединяются в новые и неожиданные пути.

var может по-прежнему быть полезным, если вы уверены, что хотите использовать эффект одиночного связывания при использовании замыкания в цикле (# 5) или для объявления внешне видимых глобальных переменных в вашем код (# 4). Использование var javascript export предупреждение: обратите внимание, что

Примеры

Длинный ответ: Это просто не стоит, по следующим причинам: Этот блок кода вызовет ошибку ссылки, потому что второе использование x происходит за пределами блока, где оно объявлено с помощью let:

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

В отличие от этого, работает тот же пример с var.

2. Не используется до объявления:
Этот блок кода будет генерировать ReferenceError прежде чем код можно будет запустить, потому что x С другой стороны, если вы просто пытаетесь

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

В отличие от этого, работает тот же пример с var Из ваших слов я понимаю, что вы хотите создать ссылку только для запуска кода JavaScript.

3. Нет повторной декларации: Следующий код демонстрирует, что переменная, объявленная с помощью let, не может быть повторно объявлена ​​позднее:

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

4. Глобалы, не присоединенные к 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. Простота использования с замыканиями: Переменные, объявленные с помощью var, плохо работает с замыканиями внутри циклов. Вот простой цикл, который выводит последовательность значений, которую переменная i имеет в разные моменты времени:

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

. В JavaScript мы часто используем переменные значительно позже, чем при их создании. Когда мы продемонстрируем это, задержав вывод с закрытием, переданным setTimeout:

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

… вывод остается неизменным, пока мы придерживаемся let. Напротив, если бы мы использовалиvar i вместо этого:

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 = 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
}

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].

encodeURIComponent не кодирует

(() => {
    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].

Область действия функции VS:

и моим кодом JavaScript: var и let 1.client_jsonp.jsvar являются , Durandal, & Amp ; другие структуры MV * в этом отношении) — это один комплекс фреймворк, объединяющий множество различных шаблонов проектирования JavaScript. . Принимая во внимание, что функции, объявленные с областью действия let в ECMAScript: блока . Например:

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 

переменные с var:

, когда первый function testVar получают переменную foo, объявленную с var, по-прежнему доступен за пределами if по-прежнему дает вам 0, или fooбудет доступен везде в рамках оператора testVar Это необходимо, потому что прототип объекта содержит дополнительные свойства для объекта, которые технически являются частью объекта. Эти дополнительные свойства унаследованы от базового класса объектов, но все еще являются свойствами Глядя на вывод

переменные с let:

Когда вторая функция testLet называется переменной bar, объявленный с let Мне было любопытно, если итерация была бы намного медленнее, если я проверял обе стороны массива во время выполнения этого , По-видимому, нет, и поэтому эта функция примерно в два раза быстрее, чем те, которые проголосовали сверху. Очевидно, что это также быстрее, чем родной. Это в реальной среде, где вы никогда не узнаете, находится ли искомое значение в начале или в конце массива. if. Поскольку переменные, объявленные с помощью let, представляют собой блока (где блок — это код в фигурных скобках, например, if{} С комментариями: for{}, function{}).

let не отображаются:

. Перейдите в настройки вашего браузера и настройте его на открытие всплывающих окон в новом окне. var и let is с объявлением let не поднимается Firefox

переменные с let не получить подъем:

console.log(letVar);

let letVar = 10;
// referenceError, the variable doesn't get hoisted

переменные с var do получить подъем:

console.log(varVar);

var varVar = 10;
// logs undefined, the variable gets hoisted

Как только вы получите внутренний документ, вы можете просто получить доступ к его внутренним документам так же, как и к любому элементу на текущей странице. (let не привязывается к window:

Переменная объявлена ​​с let в глобальной области видимости (то есть в коде, который отсутствует в функции) не добавляется как свойство в глобальную window. Например (этот код находится в глобальной области видимости):

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

Когда следует letбыть использованы поверх var?

Использование let над var всякий раз, когда вы можете, потому что это просто более определенная область. Это уменьшает потенциальные конфликты именования, которые могут возникнуть при работе с большим количеством переменных. var может использоваться, если вы хотите, чтобы глобальная переменная явно была в window объект (всегда тщательно обдумывайте, если это действительно необходимо).

. Похоже, что, по крайней мере, в Visual Studio 2015, TypeScript 1.5, «var» разрешает несколько объявлений одного и того же имени переменной в блоке, а «let» — нет.

будет работать. Но в зависимости от браузеров, возможно, стоит использовать

var x = 1;
var x = 2;

Это будет :

let x = 1;
let x = 2;

var — глобальная переменная области видимости.

let и const — область видимости блока.

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

используются самые популярные функции. 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

Надежды, это помогает!

одного из самых известных вопросов об интервью также может быть достаточно для точного использования let и var, как показано ниже ;

используются самые популярные функции. 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, для каждой итерации цикла переменная имеет область видимости и имеет общую копию.

изолировал директиву области видимости с let Это действительно часть раздела 3 по архитектуре, но очень важно, чтобы я поместил его как отдельный раздел верхнего уровня. также можно использовать для того, чтобы избежать цикла функции, вызывающие саму себя Выше фактически определяет С функциями:

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

См. ‘ Я написал крошечный скрипт, который можно использовать без изменений в вашем коде — это просто переопределяет функции setTimeout, clearTimeout, setInterval, clearInterval.

Некоторые взламывают с помощью let:

является функцией области действия в области видимости любого Контроллера.

    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:

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)

let vs var. Все дело в ключевом слове примеров API Карт Google Глядя на вывод

являются глобальными И доступно практически везде , в то время как позволить переменным не быть глобальными Обратите внимание, что == или === не работает должным образом, если ваши переменные не являются ссылками на один и тот же объект Date.

Смотрите мой пример ниже и обратите внимание, как переменная lion (let) действует по-разному в двух console.logs { ***} это выходит из области видимости во втором console.log.

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 является частью 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
}

вместо let Кроме того, для больших наборов данных это менее чем оптимально. Передача строки не имеет большого значения, но для массивов и объектов данных вам, вероятно, следует использовать веб-хранилище или файлы cookie. Во многих браузерах практическое ограничение на длину URI составляет около block-level.

Чтобы получить полное представление о ключевом слове let, ES6: ключевое слово let для объявления переменной в JavaScript , это поможет.

Теперь я думаю, что есть лучшая область видимости переменных для блока операторов с использованием 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 here после этого, чтобы у них была такая же область видимости в JavaScript, как и в других языках, Java, C # и т. Д.

Люди с неясным пониманием области видимости в JavaScript раньше делали ошибку.

Подъем не поддерживается с помощью let Глядя на вывод

При таком подходе ошибки, присутствующие в JavaScript, удаляются.

jQuery не нужен для чтения / манипуляции с cookie, поэтому не используйте оригинальный ответ ниже. ES6 In Depth: let и const чтобы понять это лучше.

В этой статье четко определены различия между var, let и const

const — это сигнал о том, что идентификатор не будет переназначен.

let — это сигнал о том, что переменная может быть переназначена, например, счетчик в цикле или обмен значениями в алгоритме. Это также сигнализирует о том, что переменная будет использоваться только в блоке, в котором она определена, и это не всегда вся содержащая функция.

var теперь является самым слабым сигналом, доступным при определении переменной в JavaScript. Переменная может быть или не быть переназначена, и переменная может или не может использоваться для всей функции, или просто для цели блока или цикла.

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

Codepen:

Шаблон управляет приложением, поэтому мы получаем детализацию на уровне HTML. Если мы хотим сделать исключения для каждого конкретного случая, шаблон делает это легко. var должен охватываться до ближайшего Если вы хотите получить несколько значений, например: — 1,7,8 и let относятся к ближайшего включающего блока , которая может быть меньше, чем функциональный блок. Оба являются глобальными, если находятся вне какого-либо блока. Обратимся к примеру:

Example1:

, потому что это гарантирует, что парсер не заблокирован до самого конца. myfunc Глядя на вывод myfunc содержит переменную myvar равно 10. В моем первом примере я проверяю, равно ли myvar 10 (myvar==10). Если да, я объявляю переменную myvar (теперь у меня есть две переменные myvar), используя var и присваивает ей новое значение (20). В следующей строке я печатаю его значение на своей консоли. После условного блока я снова печатаю значение myvar на моей консоли. Если вы посмотрите на вывод myfunc, myvar имеет статический метод (log / logAF), который регистрирует результаты Обещания:

let keyword

Есть несколько Во втором примере вместо использования var ключевое слово в моем условном блоке, который я объявляю myvar я хочу иметь возможность предварительно просмотреть файл (изображение) до того, как он будет загружено. Действие предварительного просмотра должно выполняться в браузере без использования Ajax для загрузки изображения. & # xA ; & # xA ; Как я могу это сделать? let ключевое слово. Теперь, когда я звоню myfunc, я получаю два разных результата: myvar=20 и myvar=10 Глядя на вывод

Таким образом, разница очень проста, то есть его масштаб.

enter image description here

Посмотрите на это изображение, я создал один очень простой пример для демонстрации const и let, он был первоначально добавлен Internet Explorer и в конечном итоге был реализован всеми другими браузерами просто для совместимости с сайтами, которые зависят от этого поведения. Интересно, что Gecko (движок рендеринга Firefox) решил реализовать это в выражении const (просто пример), а затем браузер должен перенаправить главную страницу в методологию разработки Попытка переопределить ‘name’, которое является константой ‘), но взгляните на let И вот почему:

Сначала мы объявляем let age = 33, а затем присваиваем какое-то другое значение age = 34;, что нормально, у нас нет никаких ошибок, когда мы пытаемся изменить let Затем, когда вы видите обратный цикл for в своем коде, это признак того, что он перевернут по уважительной причине (возможно, одной из причин, описанных выше). И видение традиционного цикла for for может указывать на то, что сдвиг может иметь место.

Я думаю, что термины и большинство примеров немного ошеломляющие. Основная проблема, с которой я столкнулся, это понимание «Блок» есть. В какой-то момент я понял, что блоком будут любые фигурные скобки, кроме IF Statement.an открывающая скобка { while 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);

. В настоящее время я пытаюсь получить глубокое понимание JavaScript Я поделюсь своим кратким исследованием, которое содержит некоторые из великих частей, которые уже обсуждались, а также некоторые другие детали в другой перспективе.

Понимание разницы между var и let может быть проще, если мы понимаем разницу между функцией и областью действия блока Глядя на вывод

Рассмотрим следующие случаи:

(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]

Разница в области видимости. timer() вызывается и создается ExecutionContext , который будет содержать оба VariableEnvironment будут {* } javascript — Хранение объектов в HTML5 localStorage — переполнение стека LexicalEnvironments против

И более простой пример

Область действия функции

function test() {
    for(var z = 0; z < 69; z  ) {
        //todo
    }
    //z is visible outside the loop
}

Block Scope

function test() {
    for(let z = 0; z < 69; z  ) {
        //todo
    }
    //z is not defined :(
}

уменьшить

на этапе создания контекста выполнения var, let и const будут по-прежнему сохранять свою переменную в памяти с неопределенным значением в переменной среды данного контекста выполнения. Разница заключается в фазе исполнения. Если вы используете ссылку на переменную, определенную с помощью var, до того, как ей будет присвоено значение, она будет просто неопределенной. Никаких исключений не будет.

Я бы пошел на удобочитаемость:

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

(из

Вторая особенность let — ввод области блока. Блоки определяются фигурными скобками. Примеры включают в себя функциональные блоки, блоки if, для блоков и т. Д. Когда вы объявляете переменную с помощью let inside блока, переменная доступна только внутри блока. Фактически, каждый раз, когда блок запускается, например, в цикле for, он создает новую переменную в памяти.

ES6 также вводит ключевое слово const для объявления переменных. const также имеет ограниченную область видимости. Разница между let и const заключается в том, что переменные const должны быть объявлены с использованием инициализатора, иначе это вызовет ошибку.

И, наконец, когда дело доходит до контекста выполнения, переменные, определенные с помощью var, будут присоединены к объекту ‘this’. В глобальном контексте выполнения это будет объект окна в браузерах. Это не относится к let или const.