Тостер
Здесь публикуются бесплатные материалы по фронтенд-разработке (ответы на вопросы, видео-уроки, статьи, тесты) Канал для разработчиков, которые хотят прокачаться до уровня Сеньора. Сотрудничество - @socubes
Ko'proq ko'rsatish1 695
Obunachilar
Ma'lumot yo'q24 soatlar
-97 kunlar
-3430 kunlar
- Kanalning o'sishi
- Post qamrovi
- ER - jalb qilish nisbati
Ma'lumot yuklanmoqda...
Obunachilar o'sish tezligi
Ma'lumot yuklanmoqda...
Photo unavailableShow in Telegram
Хотите быть в курсе происходящего в сфере информационных технологий, искусственного интеллекта, узнавать о интересных технологических новинках одним из первых?
Тогда приходите за ежедневной порцией новостей на канал "Осторожно, АйТи" 👈
Javascript: базовые вопросы
Раз уж мы коснулись стрелочных функций, а это ещё один musthave вопрос на собеседованиях, то давайте, наконец, перечислим отличия стрелочных функций от обычных.
Синтаксис, но это настолько очевидно, что и говорить не стоит.
Наличие неявного return (хотя это тоже можно отнести к синтаксису, вероятно).
Контекст и привязка значения к this. У обычных функций контекст динамически создаётся в зависимости от того, как они были вызваны, у стрелочных наследуется контекст, в котором она была создана.
Использование call, apply и bind. У обычной функции значение к this можно привязать с помощью Function.prototype методов call, apply и bind. Их можно использовать со стрелочной функцией, но изменить значение this не выйдет.
Функции‑конструкторы. Обычные функции можно использовать как конструктор, стрелочные ― нет. Это связано с тем, что они не создают свой контекст.
Обычные функции могут быть и функциональными выражениями, и именованными функциями. Стрелочные выступают только как функциональные выражения.
Всплытие. Так как стрелочные функции ― исключительно функциональные выражения, то и всплыть, как обычные функции, они не могут. Они делают это согласно поведению переменных, в которые были присвоены для дальнейшего вызова.
У стрелочных функций нет массива arguments. В большинстве случаев лучшей заменой объекта arguments в стрелочных функциях являются остаточные параметры.
В стрелочный функциях не может быть использовано ключевое слово yield (за исключением случаев, когда разрешается использовать в функциях, вложенных в тело стрелочной функции). Как следствие, стрелочные функции не могут быть использованы как генераторы.
#JSInterviewquestions
Javascript: базовые вопросы
Arrow functions и их отношения с контекстом
А вот уже ES6 представила нам новую возможность борьбы за this. Этим способом стали стрелочные функции. Все дело в том, что в отличие от обычных, они не создают собственного контекста. Они наследуют контекст, в котором были созданы, а вместе с этим у них отсутствует своё привязывание значения к this. Где бы и как они не вызывались, это никак не влияет на значение this.
Смотрим на практике.
class
Hero
{
constructor
(heroName) {
this.heroName = heroName || 'Default'
// Получить список каждого элемента в документе
let
elements = document.getElementsByTagName('button');
// Добавить callback как обработчика кликов
for
(
let
i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', this.log)
}
}
log = () => {
console.log(this.heroName);
}
}
const
batman =
new
Hero('Batman')
Мы просто переделали log, теперь это функциональное выражение, которое описано стрелочной функцией. Жмём и смотрим.
> Batman
Идеально!
Кстати, если попробовать вызвать метод bind для привязывания конкретного значения к this, это не сработает. Можете проверить самостоятельно.
Но не думайте, что стрелочные функции безупречны и применимы везде. Давайте вспомним, как мы пытались взаимодействовать с объектом напрямую, без классов и функций конструкторов.
let
a = {
name: 'Name',
log:
function
() {
console.log(this)
},
logArrow: () => console.log(this)
}
a.log()
a.logArrow()
Сразу модифицировали объект, добавили атрибут logArrow, который описан стрелочным функциональным выражением, и пробуем узнать, что у нас за значение this в log и logArrow.
> {name: 'Name', log: ƒ, logArrow: ƒ}
> Window {window: Window, self: Window, document: document, name: 'MyConstructor', location: Location, ...}
И понимаем, что в данной ситуации arrow function ведёт себя не так, как хотелось бы. Почему?
Да всё просто. Описанный таким образом объект
― это не функция, так что контекста у него нет. Наш logArrow унаследовал тот, что ближе лежал,
― глобальный. this, стало быть, ссылка на window, как и полагается в глобальном контексте.
#JSInterviewquestionsRepost from OSINT library
Photo unavailableShow in Telegram
Search4faces: сервис, который поможет найти человека по фотографии в социальных сетях | #osint_programs
Search4faces — это сервис, предназначенный для поиска людей в интернете на основе фотографий. Используя технологии нейронных сетей и машинного обучения, он обещает помочь пользователям найти нужного человека или кого-то, очень на него похожего, всего за несколько секунд.
Результатом поиска является ссылка на профиль найденного человека в социальных сетях, таких как Вконтакте, Клабхаус, Одноклассники, Тикток, а в будущем планируется расширение и на другие платформы.
Детальнее — на нашем сайте.
osint library
Photo unavailableShow in Telegram
Search4faces: сервис, который поможет найти человека по фотографии в социальных сетях | #osint_programs
Search4faces — это сервис, предназначенный для поиска людей в интернете на основе фотографий. Используя технологии нейронных сетей и машинного обучения, он обещает помочь пользователям найти нужного человека или кого-то, очень на него похожего, всего за несколько секунд.
Результатом поиска является ссылка на профиль найденного человека в социальных сетях, таких как Вконтакте, Клабхаус, Одноклассники, Тикток, а в будущем планируется расширение и на другие платформы.
Детальнее — на нашем сайте.
osint library
Javascript: базовые вопросы
Исправление ошибок привязки значения к this
Были у нас способы привязки значения к this с помощью методов прототипа Function call и apply, но в нашей ситуации они нам не очень помогут (вообще не помогут). Мы не можем сразу вызвать функцию callback, ведь она ещё не дождалась своего часа.
Но в современном Javascript есть способы справиться с ситуацией.
Привязка значения к this с помощью Function.prototype.bind()
Метод этот пришел вместе с ES5, и в отличие от своих соратников call и apply, он не вызывает функцию. В результате своего исполнения он возвращает новую функцию, которая при выполнении будет устанавливать в значение this то, что мы передали в качестве первого аргумента.
Применяем на практике.
class
Hero
{
constructor
(heroName) {
this.heroName = heroName || 'Default'
// Получить список каждого элемента в документе
let
elements = document.getElementsByTagName('button');
// Добавить callback как обработчика кликов
for
(
let
i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', this.log.bind(this))
}
}
log
() {
console.log(this.heroName);
}
}
const
batman =
new
Hero('Batman')
Жмём на нашу изящную кнопку и смотрим в консоль.
> Batman
Спойлер! C setTimeout тоже сработает.
#JSInterviewquestionsPhoto unavailableShow in Telegram
Хотите стать разработчиком, но не определились с языком программирования?
Ждем вас на бесплатном вебинаре 15 июня в 19:00 по мск.
✔️ Разбираем профессию “Фронтенд-разработчик” и кому она подходит.
✔️ Пробуем на практике: вместе пишем мини-игру на JS.
✔️ Говорим о первой работе для новичков без опыта.
🎁 Дарим “Карту компетенций”, гайд «Как опубликовать страницу в интернете при помощи GitHub Pages» и «Как заговорить на сленге IT-специалистов», а еще бонусы на обучение профессии!
Javascript: базовые вопросы
Как теряется контекст?
При определённых условиях контекст легко потерять и потом сидеть и ломать голову, почему же так произошло. Особенно это актуально было в более ранних версиях реакт, в классовых компонентах. Но это частный случай, а мы рассмотрим общий.
Вернёмся к классу Hero, который уже был нами создан на определённом этапе разбора способов вызова функции. Только немного его модифицируем.
class
Hero
{
constructor
(heroName) {
this.heroName = heroName || 'Default'
}
log
() {
console.log(this.heroName);
}
asyncLog
() {
setTimeout(this.log, 5000)
}
}
const
batman =
new
Hero('Batman')
batman.log()
batman.asyncLog()
В общем, добавили прототипу нашего объекта ещё один метод логирования, да ко всему прочему сделали его асинхронным.
В итоге в конце скрипта вызываем синхронный log, а за ним asyncLog и сравниваем результаты.
> Batman
> undefined
И вот она — магия во всей красе. Мы его потеряли. Хотя, казалось бы, асинхронный лог не делает ничего сверхъестественного, кроме как выполняет тот же log, но с задержкой.
Почему же имя героя исчезло?
По умолчанию внутри window.setTimeout() this устанавливается в объект window.
И ещё раз модифицируем наш класс.
И делаем так, что выводить в консоль имя героя мы хотим при клике на кнопку.
class
Hero
{
constructor
(heroName) {
this.heroName = heroName || 'Default'
// Получить список каждого элемента в документе
let
elements = document.getElementsByTagName('button');
// Добавить callback как обработчика кликов
for
(
let
i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', this.log)
}
}
log
() {
console.log(this.heroName);
}
}
const
batman =
new
Hero('Batman')
Нажмём на кнопку.
> undefined
Тут опять же все прозрачно. У нас в колбеки ивент листенеров this отправляется ссылка на элемент DOM, а у него опять же нет heroName.
Для примера более чем достаточно. Какой делаем вывод? Что «контекст не теряется», он просто становится другим и уже не удовлетворяет наши потребности.
#JSInterviewquestionsJavascript: базовые вопросы
IIFE - immediately invoked function expression
Они же - самовызывающиеся функции.
(
function
(){
console.log(this === window)
})()
Вывод в консоль:
> true
#JSInterviewquestionsBoshqa reja tanlang
Joriy rejangiz faqat 5 ta kanal uchun analitika imkoniyatini beradi. Ko'proq olish uchun, iltimos, boshqa reja tanlang.