Сбивающие с толку переменные области действия функции.
Когда мы используем ключевое слово var в ES5, объявляется переменная и область действия функции. Таким образом, приведенный ниже пример приводит к некоторому странному поведению:
var bar = 0; function doSome(foo){ if(foo){ var bar = 1; return bar; } return bar; } doSome(false); // undefined :(
Переменный подъем
Объявления переменных обрабатываются раньше всего в области видимости функции. Таким образом, предыдущий блок кода имеет больше смысла, когда он записывается по мере его обработки, например:
var bar = 0; function doSome(foo){ var bar; if(foo){ bar = 1; return bar; } return bar; } doSome(false); // undefined
Такое поведение известно как подъем переменных и хорошо объяснено на MDN.
Здравствуйте, const
Когда мы хотим объявить постоянное значение, мы обычно ищем неизменяемость. В ES5, как правило, программисты определяют константы по соглашению, например так:
var NOT_SUPPOSED_TO_CHANGE = 'foo';
Однако это всего лишь соглашение, не обеспечивающее неизменности:
var NOT_SUPPOSED_TO_CHANGE = 'foo'; function changeConstant(val){ NOT_SUPPOSED_TO_CHANGE = 'bar'; return NOT_SUPPOSED_TO_CHANGE; } changeConstant(NOT_SUPPOSED_TO_CHANGE); // 'bar'
Итак, с введением const в ES2015 мы получаем неизменяемые константы, верно?
const NOT_SUPPOSED_TO_CHANGE = 'foo'; NOT_SUPPOSED_TO_CHANGE = 'bar' // throws an exception "Assignment to constant variable"
Однако это не конец истории.
const AM_I_IMMUTABLE = { foo : 'bar' }; AM_I_IMMUTABLE.foo = 'baz'; // 'baz' ... WTF!?
Оказывается, константа на самом деле не означает неизменяемость. Это означает, что привязка значения не может быть повторена, и, как объясняется в статье, если вы ищете неизменность, вы можете попробовать Object.freeze().
Здравствуйте, позвольте
Как и в случае с var, когда мы привязываем значение к переменной, мы ожидаем, что ее значение может измениться.
function foo(val, doFoo){ var iCanChange = 1; function bar(){ if(doFoo){ var iCanChange = 0; return iCanChange; } iCanChange += 5; return iCanChange; } return val + iCanChange + bar(); } foo(3, false);// NaN foo(3, true);// 104
Однако и let, и const имеют блочную область видимости, что означает, что вы получите довольно разные результаты:
function foo(val, doFoo){ let iCanChange = 1; function bar(){ if(doFoo){ let iCanChange = 100; return iCanChange; } iCanChange += 5; return iCanChange; } return val + iCanChange + bar(); } foo(3, false);// 10 foo(3, true);// 104
Явная область видимости блока
Благодаря статье Дэвида Уолша эта тема освещена очень подробно. Чтобы сделать ваши объявления let понятными и явными, вы можете объявить их в голых блоках.
let foo = 99; { let foo = 1; console.log(foo); } console.log(foo); // outputs // 1 // 99
Это пока все, что я могу найти по этому вопросу. Вперед.