хуйу нас не матерятся
Первый вопрос который я задаю на собеседовании - вопрос о переменных. Вопрос крайне простой, но половина кандидатов, даже с опытом работы, отвечают никак, либо очень плохо.
И так, я пишу 4 способа объявления переменных и прошу рассказать о них всё что кандидат знает:
test1 = 1;
var test2 = 2;
let test3 = 3;
const test4 = 4;
Давайте поясню что тут к чему:
test1 = 1;
Объявляется глобальная переменная, с глобальной областью видимости. Если код выполняется в браузере, то переменная становится свойством объекта window, то есть test1 = 1 равносильно window.test1 = 1. В node.js есть специальная переменная global, то есть будет global.test1 = 1.
'use strict'
test1 = 1; // ошибка
В strict mode запрещено объявление глобальных переменных, если в strict mode объявить глобальную переменную то получим "ReferenceError: test1 is not defined".
var test2 = 2;
Директива var объявляет переменную с функциональной областью видимости. На самом деле наш скрипт, даже если он состоит только из объявления переменной- это функция, и при запуске, будет исполнен код вида:
(function() {
var test2 = 2;
} ())
И в итоге область видимости не выйдет за пределы свой родительской функции. Теперь более подробный пример:
var test1 = 1;
var test2 = 2;
function testFunc() {
test1 = 10;
var test2 = 3;
console.log(test1, test2); // покажет: 10 3
}
testFunc();
console.log(test1, test2); // покажет: 10 2
Внутри функции testFunc, нет ключевого слова var для test1, по этому используется переменная, объявленная ранее, в родительской функции. Для test2 есть ключевое слово var, по этому будет создана новая переменная, с областью видимости внутри testFunc, при этом test2 объявленная родителем не будет изменения.
После того, как testFunc выполнится, test2 объявленная внутри testFunc будет уничтожена, и во втором консольлоге будет видна test2 со значением 2.
let test3 = 3;
Ключевое слово let объявляет переменную с блочной областью видимости, блок кода - это код внутри фигурных скобок {}.
let test1 = 1;
{
let test2 = 2;
}
console.log(test1); // покажет 1
console.log(test2); // ошибка "ReferenceError: test2 is not defined"
И ещё 1 пример поясняющий отличия между let и var:
for(var test1=1; test1<=5; test1++) {
console.log(test1); // покажет цифры от 1 до 5
}
console.log(test1); // покажет 6, т.к. переменная осталась в области видимости текущей функции
for(let test2=1; test2<=5; test2++) {
console.log(test2); // покажет цифры от 1 до 5
}
console.log(test2); // ошибка "ReferenceError: test2 is not defined", потому что test2 не может быть доступна за пределами своего блока кода
И напоследок объявление константы:
const test4 = 4;
Если константе присваивается любой простой тип данных: число, строка, символ итд, то изменить значение константы нельзя. Если константе присваивается объект, то этой константе нельзя присвоить новый объект, но можно изменять свойства объекта, пример константа с числовыми данными:
const test1 = 1;
test1 = 2; // Ошибка "TypeError: Assignment to constant variable."
И константа с объектами:
const test1 = {
a: 1,
b: 2
};
test1.a = 2; // так будет работать
test1 = { // а вот так уже нет
c: 3,
b: 4
}
Область видимости у констант в JavaScript блочная, так же как у let:
const test1 = 1;
{
const test2 = 2;
}
console.log(test1); // 1
console.log(test2); // ReferenceError: test2 is not defined
И второй пример:
const test1 = 1;
(function(){
const test2 = 2;
console.log(test1); // 1
console.log(test2); // 2
}())
console.log(test1); // 1
console.log(test2); // ReferenceError: test2 is not defined