После окончания школы Flatiron я проинтервьюировал несколько компаний и записал все вопросы, которые мне задавали. В этой серии будут представлены общие концепции Javascript, которые задаются во время собеседований с разработчиками программного обеспечения.
- Первый вопрос: что это предупредит?
Предупреждение о спойлере - объяснение ниже
Это классический вопрос о замыканиях и функциях против области видимости блока. Поскольку var является областью видимости функции, он существует в createButtons()
, а не в цикле for. Следовательно, задолго до того, как клиент щелкнет кнопки и проверит предупреждающее сообщение, цикл for будет полностью выполнен, и var i
станет равным 6, поэтому нажатие любой кнопки предупреждает «Это кнопка 6». При использовании var область видимости не ограничивается блоком, в котором используется переменная, - вместо этого она охватывает либо область действия следующей наивысшей функции, либо глобальную область видимости. С другой стороны, let и const привязаны к блоку, поэтому они живут только в течение времени жизни своего блока. Изменение var i
на let i
делает i
другим при каждом запуске блока цикла, поэтому текущий i
будет сохранен.
Другой способ - вызвать функцию, передав текущую i
цикла;
Таким образом, у цикла for нет другого выбора, кроме как передавать текущее значение i функции на каждом проходе цикла.
То же самое можно было бы переписать как IIFE, избегая необходимости вызова внешней функции;
2. Больше по теме var vs let, но что касается подъема, подумайте, что будет выводиться из следующего;
Предупреждение о спойлере - объяснение ниже
Он специально написан таким образом, что переменные потребляются выше, где они инициализируются и им присваиваются значения. Переменная с использованием var; area
выдает ошибку как undefined
при использовании переменной let; name
ошибки выводятся как Reference Error
. Во время компиляции Javascript выполняет объявления переменных, затем повторно запускается для выполнения всех назначений переменных, чтения и вызова функций. На первом этапе переменные поднимаются наверх и получают предварительные значения по умолчанию. С помощью var переменным при начальном запуске присваиваются значения undefined. С let переменным ничего не присваивается (typeof
будет равно строке ‘undefined’
). Поэтому попытка использовать имя вызывает ошибку ссылки. Лучше всего писать все объявления и назначения переменных в верхней части их области видимости. В противном случае реализуйте обработку ошибок следующим образом:
3. Объясните ключевое слово this
и его использование.
this
- это держатель ссылки, который будет ссылаться на разные значения в зависимости от области действия и способа ее вызова.
Когда this
используется в глобальной области видимости, он относится к объекту окна (кроме строгого режима)
Когда this
используется в объекте, это относится к объекту, в котором он находится.
Когда this
используется в методе объекта, он ссылается на родительский элемент этого метода; объект. В классе this
относится к классу
Когда this
используется в отдельной функции, он относится к родительскому элементу этой функции, который будет глобальным объектом окна.
При использовании this
в функциях лучше всего сделать их функциями стрелок. Таким образом, внешняя область видимости будет искаться для определения контекста this.
Стрелочные функции не привязаны к this.
Однако, когда функции передаются другим функциям или устанавливаются в переменные, которые будут использоваться в любой возможной области и контексте, this
теряет свою ссылку. В этих случаях контекст this
должен быть явно указан с использованием call
, apply
или bind;
синтаксис вызова: passedFunction.call(obj, arg1, arg2, ..)
, где passedFunction
- это функция, использующая this
, obj
- это объект, к которому будет привязана функция this
, а оставшиеся args
- аргументы, передаваемые ей (поскольку call
- это вызов).
Применить: - то же, что и call
, но аргументы передаются в виде массива; someFunction.call(obj, [arg1, arg2])
Бинд в отличие от call
и apply
, в bind
, someFunction
вызывается не сразу. Его помещают в переменную, которая будет вызываться позже; someFunction.bind(obj)
Подводя итоги, в этой части серии интервью по Javascript мы раскрыли различия между var и let с точки зрения их области действия и подъема. Мы также описали различные значения, которые это принимает в зависимости от контекста, и то, как обеспечить это значение с помощью методов call, apply или bind.