В чем разница между использованием "let" и "var" для объявления переменной в JavaScript?
ECMAScript 6 введен на let
сообщении. Я слышал, что он описывается как "локальная" переменная, но я все еще не совсем уверен, как она ведет себя иначе, чем var
ключевое слово.
В чем разница? Когда let
использоваться по var
?
27 ответов
разница в области. var
действует до ближайшего функционального блока и let
действует до ближайшего вшита блок, который может быть меньше функционального блока. Оба являются глобальными, если за пределами любого блока.
кроме того, переменные, объявленные с let
недоступны до того, как они будут объявлены в их заключительном блоке. Как видно из демонстрации, это вызовет исключение 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>
общие:
они очень похожи при использовании как это вне функционального блока.
let me = 'go'; // globally scoped
var i = 'able'; // globally scoped
однако глобальные переменные определяются с помощью let
не будут добавлены в качестве свойств на глобальном window
объект, как те, которые определены с 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
виден для всей функции.
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:
предполагая строгого режима, var
позволит вам повторно объявить ту же переменную в той же области. С другой стороны,--9--> не будет:
'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
можно также использовать для избежания проблем с закрытиями. Он связывает новое значение, а не сохраняет старую ссылку, как показано в примерах ниже.
for(var i = 1; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
код выше демонстрирует классическую проблему закрытия JavaScript. Ссылка на i
переменная хранится в закрытии обработчика щелчка, а не фактическое значение i
.
каждый обработчик щелчка будет ссылаться на один и тот же объект потому что есть только один встречный объект, который содержит 6, поэтому вы получаете шесть на каждый клик.
общий обходной путь-обернуть это в анонимную функцию и передать i
в качестве аргумента. Таких проблем также можно избежать, используя let
вместо var
как показано в ниже код.
демо (протестировано в Chrome и Firefox 50)
'use strict';
for(let i = 1; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
здесь объяснение let
ключевое слово С некоторыми примерами.
let работает очень похоже на var. Основное отличие заключается в том, что область переменной var-это вся заключающая функция
в этой таблице в Википедии показано, какие браузеры поддерживают Javascript 1.7.
обратите внимание, что его поддерживают только браузеры Mozilla и Chrome. То есть, Safari, и потенциально другие не делают.
в чем разница между let
и var
?
- переменная, определенная с помощью
var
заявление известно во всем функции он определяется в, с самого начала функции. (*) - переменная, определенная с помощью
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
известно только в первом цикле, но не до и после. Еще, наши переменной i
известно во всей функции.
кроме того, учтите, что переменные области блока не известны до их объявления, потому что они не поднимаются. Вы также не можете повторно объявить тот же блок, область действия переменная в пределах одного блока. Это делает переменные области блока менее подверженными ошибкам, чем глобально или функционально переменные области, которые поднимаются и которые не производят ошибок в случае нескольких объявлений.
безопасно ли использовать let
сегодня?
некоторые люди будут утверждать, что в будущем мы будем использовать только операторы let и что операторы var станут устаревшими. Гуру в JavaScript Кайл Симпсон написал очень продуманная статья о том, почему это не так.
сегодня, однако, это определенно не тот случай. На самом деле нам нужно спросить себя, безопасно ли использовать let
заявление. Ответ на этот вопрос зависит от вашего окружения:
если вы пишете серверный код JavaScript (узел.js), вы можете смело использовать
let
заявление.если вы пишете клиентский код JavaScript и используете транспилер (например,Трейсер), вы можете смело использовать
let
оператор, однако ваш код, вероятно, будет чем угодно, но не оптимальным по производительности.если вы пишете клиентский JavaScript-код и не используете транспилер, вам необходимо рассмотреть поддержку браузера.
Сегодня, 8 Июня 2018, есть еще некоторые браузеры, которые не поддерживают let
!
как отслеживать поддержку браузера
для обновленного обзора того, какие браузеры поддерживают let
заявление во время чтения этого ответа см. этой Can I Use
страница.
(*) глобальные и функциональные переменные могут быть инициализированы и использованы до их заявил, что переменные JavaScript подняли. это означает, что объявления всегда находятся в верхней части области.
(**) переменные области блока не поднимаются
в принятом ответе отсутствует точка:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
есть некоторые тонкие различия -- let
scoping ведет себя больше как переменная scoping делает в более или менее любых других языках.
например, он распространяется на заключительный блок, они не существуют до их объявления и т. д.
однако стоит отметить, что let
является только частью новых реализаций Javascript и имеет различную степень поддержка браузеров.
вот пример разницы между ними (поддержка только что началась для chrome):
Как видите,var j
переменная по-прежнему имеет значение вне области цикла for (область блока), но let i
переменная не определена вне области цикла.
"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
блок рамки
переменные, объявленные с помощью let
ключевое слово блочная область видимости, что означает, что они доступны только в блок, в котором они были объявлены.
на верхнем уровне (вне функции)
на верхнем уровне, переменные, объявленные с помощью 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
внутри функции
внутри funciton (но за пределами квартала),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
в циклах можно ссылаться только внутри этого цикла.
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.
петли с замыканиями
если вы используете 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
С тем же идентификатором, что и другая переменная, которая была объявлена с помощью 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. Однако есть две вещи, которые отличаются друг от друга.
нет повторного назначения
переменная, объявленная с помощью const
не может быть повторно назначен.
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
обратите внимание, что это не значит, что значение является неизменяемым. Свои свойства все еще могут быть изменен.
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
если вы хотите иметь неизменный объект, вы должны использовать Object.freeze()
.
инициализатор требуется
вы всегда должны указать значение при объявлении переменной с помощью const
.
const a; // SyntaxError: Missing initializer in const declaration
-
Переменная Не Подниматьlet
будет не Тали для всего объема блока, в котором они появляются. Напротив,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
поднял. -
Вывоз Мусора
объем блока
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
в цикле can повторно связывает его для каждой итерации цикла, убедитесь, что повторно присвоить ему значение из конца предыдущей итерации цикла. Подумай,
заменить// 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
создайте новую лексическую среду с этими именами для A) инициализатора выражение b) каждая итерация (предварительно для оценки выражения приращения), более подробная информация здесь.
главным образом разница область разница, в то время как пусть может быть доступен только внутри объявленной области, как в for loop,var можно получить доступ за пределами цикла, например. Из документации в MDN (примеры также из MDN):
пусть позволяет объявлять переменные, ограниченные по области действия блоком, инструкцией или выражением, в которых они используются. Это не похоже на var ключевое слово, которое определяет переменную глобально, или локально для целой функции независимо от объема блока.
переменные, объявленные пусть имеют в качестве своей области блок, в котором они определены, а также в любых содержащихся подблоках. Таким образом, пусть работает очень похоже на var. Основное отличие заключается в том, что объем a 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
}`
на верхнем уровне программ и функций, пусть в отличие от 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, так что это пока не полностью поддерживается, так что лучше всегда transpiles его ECMA5 используя Бабеля и т. д... для получения дополнительной информации о визите веб-сайт babel
вот пример, чтобы добавить к тому, что другие уже написали. Предположим, вы хотите создать массив функций, adderFunctions
, где каждая функция принимает один числовой аргумент и возвращает сумму аргумента и индекса функции в массиве. Попытка создать 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
. Это совсем не то, что мы хотели: теперь у нас есть массив из 1000 различных функций в памяти с точно таким же поведением. И если мы впоследствии обновим значение 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
ведет себя так, как ожидалось.
теперь изображение смешивает два поведения, и вы, вероятно, увидите, почему не рекомендуется смешивать новые 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
не позволяйте этому случиться с вами. Используйте Линтер.
Примечание: это обучающий пример, предназначенный для демонстрации
var
/let
поведение в циклах и с замыканиями функций, которые также было бы легко понять. Это был бы ужасный способ сложения чисел. Но общий метод захвата данных в анонимных замыканиях функций может встретиться в реальном мире в других контекстах. YMMV.
разницу в область переменных, объявленных с каждым.
на практике существует ряд полезных последствий разницы в объеме:
-
let
переменные видны только в их ближайшего объемлющего блока ({ ... }
). -
let
переменные можно использовать только в строках кода, которые происходят после переменная объявлена (хотя они лапы!). -
let
переменные не могут быть повторно объявлены последующимvar
илиlet
. - глобальные
let
переменные не добавляются в глобальный
могут следующие две функции показать разницу:
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].
, тогда как
(() => {
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].
также кажется, что, по крайней мере, в Visual Studio 2015, TypeScript 1.5, "var" допускает несколько объявлений одного и того же имени переменной в блоке, а "let" - нет.
это не приведет к ошибке компиляции:
var x = 1;
var x = 2;
Это:
let x = 1;
let x = 2;
Если я прочитаю спецификации прямо тогда 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
посмотретьэмуляция приватных интерфейсов'
некоторые хаки с 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"
геттер и сеттер с 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
на 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 является частью 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
}
функция против области блока:
основное различие между var
и let
это переменные, объявленные с var
are
ранее в JavaScript было только две области, т. е. функциональная и глобальная. С 'let
' ключевое слово JavaScript теперь введено 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 здесь после того, как они будут иметь аналогичную область в JavaScript, как и другие языки, Java, C# и т. д.
люди с неясным пониманием области в JavaScript, используемые для совершения ошибки ранее.
подъем не поддерживается с помощью let
.
при таком подходе ошибки присутствуют в JavaScript удаляются.
смотрите ES6 в глубину: пусть и const чтобы понять это лучше.
эта статья четко определяет разницу между var, let и const
const
- Это сигнал о том, что идентификатор не будет переназначен.
let
, является сигналом о том, что переменная может быть переназначена, например счетчик в цикле или своп значений в алгоритме. Он также сигналов что переменная будет использоваться только в блоке, в котором она определена, который не всегда является всей содержащей функцией.
var
сейчас самый слабый сигнал, доступный при определении переменной в JavaScript. Переменная может быть или не может быть переназначена, и переменная может использоваться или не использоваться для всей функции или только для назначение блока или петли.
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b
ECMAScript 6 добавлено еще одно ключевое слово для объявления переменных, отличных от" Let".
основная цель введения "let" и "const" над " var " состоит в том, чтобы иметь блочный охват вместо традиционного лексического. эта статья очень кратко объясняет разницу между "var" и "let", а также охватывает обсуждение "const".
проверьте эту ссылку в MDN
let x = 1;
if (x === 1) {
let x = 2;
console.log(x);
// expected output: 2
}
console.log(x);
// expected output: 1