Мы вам перезвоним pinned «Ах да, совсем забыл, ответы и свои вопросы присылайте мне на @djamah И помните, для этого канала нет плохих вопросов, а есть плохие разборы (хотя, плохих разборов тоже нет). Пишите!)»
#Задачка7 висела без разбора дольше остальных, но и ответов на нее пришло больше всего.
Многие из них были правильными, а некоторые даже пытались соответствовать условию))
Первым правильный ответ прислал Евгений, а заметил ошибку в условии — Дима, но обо всем по порядку.
Основная проблема #Задачка7 в том, что функция должна быть одновременно и функцией, ведь в любой момент можно приписать пару скобок, и числом.
Вернуть из функции саму себя и посчитать количество таких вызовов — дело нехитрое:
Вопрос в том, как сделать, чтобы возвращаемая функция была одновременно числом.
И тут нам на помощь приходит то, что джаваскрипт пытается нам помогать, дергая всякие внутренние методы, когда по типам что-то не сходится, и первый из них, конечно же
Код вроде такого является правильным решением задачи.
Некоторые из вас воскликнут: НО ТАМ ЖЕ БЫЛО
Ну что вам сказать? Да, в консоль логах должно было быть двойное равно, а я лоханулся. Но вы это, не стесняйтесь уточнять)
p.s. Использовать
Многие из них были правильными, а некоторые даже пытались соответствовать условию))
Первым правильный ответ прислал Евгений, а заметил ошибку в условии — Дима, но обо всем по порядку.
Основная проблема #Задачка7 в том, что функция должна быть одновременно и функцией, ведь в любой момент можно приписать пару скобок, и числом.
Вернуть из функции саму себя и посчитать количество таких вызовов — дело нехитрое:
var count = 0;
function f() {
count++;
return f;
}
Вопрос в том, как сделать, чтобы возвращаемая функция была одновременно числом.
И тут нам на помощь приходит то, что джаваскрипт пытается нам помогать, дергая всякие внутренние методы, когда по типам что-то не сходится, и первый из них, конечно же
valueOf
.var count = 0;
function f() {
count++;
return f;
}
f.valueOf = function() {
return count;
}
Код вроде такого является правильным решением задачи.
Некоторые из вас воскликнут: НО ТАМ ЖЕ БЫЛО
===
!!1, а при строгом сравнении это работать не будет!Ну что вам сказать? Да, в консоль логах должно было быть двойное равно, а я лоханулся. Но вы это, не стесняйтесь уточнять)
p.s. Использовать
toString
вместо valueOf
тоже ок.Пока я пишу ответ к прошлой задаче, Михаил прислал кое-что из классики:
#Задачка9
Что выведется в консоль? Почему?
#Задачка9
const a = {};
const b = {key: 'b'};
const c = {key: 'c'};
a[b] = 12;
a[c] = 42;
console.log(a[b]);
Что выведется в консоль? Почему?
Всем привет, а я про вас не забыл, просто у нас тут в Африке как-то хуже с интернетом, чем у вас в Европах)
Долгожданный ответ к #Задачка8
Ну первое, что нельзя не прокомментировать - это задание прототипа через свойство
Впрочем, очевидно, что к заданию это не относится. И мы были бы не мы, если бы не поумничали, и снисходительно не заметили, что это, конечно, на суть задания не влияет, но в пул реквесте реального проекта мимо проходить нельзя.
Теперь, что там у нас дальше? А дальше происходит удаление свойств из объекта и важно не забыть, как это там работает с прототипами.
Работает очень просто, как и всегда с прототипами нужно помнить: на запись — только собственные свойства, а на чтение — можно и из родителя.
Удаление свойства — это считается как запись.
С первыми тремя консоль логами все просто:
Здесь удаляется собственное свойство
Потом следует повторение этих двух строк и так как на запись (в нашем случае — удаление) доступны только собственные свойства, то он попыпается удалить то чего уже нет, а в прототип не полезет, потому что нельзя ему, и в консоли мы увидим снова
Со строчками
тоже все ясно, удаляется ссылка на объект
Ну и самое интересное в этой задачке — последняя пара строк:
В консоль выведется
Этот эффект объясняется очень просто: в обращении
Когда я разбирал эту задачку в докладе, я написал эквивалентный код:
В нем, мне кажется, хорошо видно, что удаляем мы собственное свойство объекта, а доступ к объекту получили по ссылке из прототипа.
Долгожданный ответ к #Задачка8
Ну первое, что нельзя не прокомментировать - это задание прототипа через свойство
__proto__
, в 2k18 это не очень правильно. Ну, это никогда не было правильно, просто раньше это еще и не работало, а теперь работает, но есть более нормальные способы задать прототип.Впрочем, очевидно, что к заданию это не относится. И мы были бы не мы, если бы не поумничали, и снисходительно не заметили, что это, конечно, на суть задания не влияет, но в пул реквесте реального проекта мимо проходить нельзя.
Теперь, что там у нас дальше? А дальше происходит удаление свойств из объекта и важно не забыть, как это там работает с прототипами.
Работает очень просто, как и всегда с прототипами нужно помнить: на запись — только собственные свойства, а на чтение — можно и из родителя.
Удаление свойства — это считается как запись.
С первыми тремя консоль логами все просто:
delete obj.a;
console.log(obj.a);
Здесь удаляется собственное свойство
a: 5
, поэтому в консоль выведется значение из прототипа — 10
Потом следует повторение этих двух строк и так как на запись (в нашем случае — удаление) доступны только собственные свойства, то он попыпается удалить то чего уже нет, а в прототип не полезет, потому что нельзя ему, и в консоли мы увидим снова
10
.Со строчками
delete obj.b;
console.log(obj.b.c);
тоже все ясно, удаляется ссылка на объект
{c: 10}
и при обращении obj.b.c
— идем в прототип и оттуда считываем 20
. Ну и самое интересное в этой задачке — последняя пара строк:
delete obj.b.c;
console.log(obj.b.c);
В консоль выведется
undefined
, и получается, что таки можно залезть в прототип и что-то там поменять.Этот эффект объясняется очень просто: в обращении
obj.b.c
та часть, которая обращается к прототипу obj.b
делает это на чтение, и мы получаем прямую ссылку на объект и уже из него удаляем собственное свойство с
.Когда я разбирал эту задачку в докладе, я написал эквивалентный код:
var temp = obj.b;
delete temp.c;
console.log(obj.b.c);
В нем, мне кажется, хорошо видно, что удаляем мы собственное свойство объекта, а доступ к объекту получили по ссылке из прототипа.
#Задачка9 хороший повод поговорить про объекты.
Объекты в js — это такие ассоциативные пары ключей и значений.
Важно помнить, что в общем(!) случае ключом может быть практически любая строка. В этом же общем случае мы обращаемся к свойствам через квадратные скобки, например,
То, что мы привыкли обращаться к свойствам через точку, — это частный случай, синтаксический сахар для случаев, когда ключом является строка без взяких специальных символов и пробелов.
Зная все это, а также то, что для приведения к строке используется метод
Первым с этим справился Дима (не тот, что в прошлые разы), а хорошо сформулировал Андрей:
Выведет в консоль
Объекты в js — это такие ассоциативные пары ключей и значений.
Важно помнить, что в общем(!) случае ключом может быть практически любая строка. В этом же общем случае мы обращаемся к свойствам через квадратные скобки, например,
obj['практически любая строка']
.То, что мы привыкли обращаться к свойствам через точку, — это частный случай, синтаксический сахар для случаев, когда ключом является строка без взяких специальных символов и пробелов.
Зная все это, а также то, что для приведения к строке используется метод
toString
и что для объектов он возвращает [object Object]
, указать правильный вариант довольно легко.Первым с этим справился Дима (не тот, что в прошлые разы), а хорошо сформулировал Андрей:
Выведет в консоль
42
, потому что в пустом объекте a
создается свойство [object Object]
из-за того, что в качестве ключа мы указываем объект и этому свойству присваивается последнее значение 42
.Давид подкинул отличную идею для задачи:
#Задачка10
А давайте придумаем свою реализацию функции
#Задачка10
А давайте придумаем свою реализацию функции
isNaN
, вот будто изначально ее нет.К #Задачка10 почти все прислали примерно такой вариант:
ведь
И это правильный ответ, но на другую задачку) Описанным образом работает
Правильный ответ что-то вроде:
Очень точно резюмировал Игорь:
"поэтому
P.S. И пожалуйста, не забывайте, что
function isNaN(n) {
return n !== n;
}
ведь
NaN
это единственное значение, которое не равно самому себе.И это правильный ответ, но на другую задачку) Описанным образом работает
Number.isNaN
, который появился только в ES6, а оригинальный isNaN
сначала приводит аргумент к числу, а уже потом проверяет, что он неравен самому себе.Правильный ответ что-то вроде:
function isNaN(n) {
n = +n; // ну или как вы там любите приводить что-то к числу
return n !== n;
}
Очень точно резюмировал Игорь:
"поэтому
isNaN({})
или isNaN('строка')
выдаст true, но новый Number.isNaN
сработает только на явно переданный NaN
."P.S. И пожалуйста, не забывайте, что
NaN
— это всего лишь специальное значение типа число. А то каждый второй, кто правильно перечисляет типы в js, на запутывающий вопрос: 'а разве NaN
не отдельный тип?' — начинает сомневаться и добавляет что-то типа: "А, ну да, забыл, NaN
также является отдельным типом", а это не так.#Задачка11
Катя прислала вопрос:
Что выведется в консоль? А почему?
P.S. Очень жду ваших ответов на @djamah, только убедитесь, что у вас есть хороший ответ и на второй вопрос)
Катя прислала вопрос:
var test = 42;
function a() {
console.log(test);
}
function b() {
var test = 13;
a();
}
b();
Что выведется в консоль? А почему?
P.S. Очень жду ваших ответов на @djamah, только убедитесь, что у вас есть хороший ответ и на второй вопрос)
Раньше всех верный и достаточно полный ответ к #Задачка11 написал Давид, ну а самый подробный прислала автор вопроса Катя, спасибо ей и почитайте, как нужно подробно разбирать даже простые задачки:
В консоль выведется
Путаница может возникнуть в том, что функция a вызывается внутри функции
Немного теории:
У функции есть скрытое свойство
И если
В примере:
Создаём глобальную переменную
Объявляем функцию a, её свойство
Объявляем функцию
При вызове функции
В консоль выведется
42
.Путаница может возникнуть в том, что функция a вызывается внутри функции
b
, в которой тоже объявлена переменная test
со значением 13
.Немного теории:
У функции есть скрытое свойство
[[Scope]]
, которое ссылается на лексическое окружение, в котором она была создана. Оно никогда не меняется. При создании функции внутри неё создаётся объект Lexical Environment, куда записываются все переменные, аргументы этой функции, а также ссылка со значением из [[Scope]]
.И если
var
не найдена внутри этого объекта, то интерпретатор будет искать её по ссылке [[Scope]]
.В примере:
Создаём глобальную переменную
test
, ей присваивается значение 42
. Объявляем функцию a, её свойство
[[Scope]]
ссылается на глобальный объект window
. Объявляем функцию
b
, внутри которой создаём переменную test
со значением 13
, и вызываем функцию a
.При вызове функции
b
внутри нее создается свой Lexical Environment, в которую записывается test = 13
. Вызываем функцию a
: интерпретатор ищет внутри функции a (то есть в её Lexical Environment) переменную test
, не находит её и идёт по ссылке [[Scope]]
. Путь приводит его в глобальную область видимости, где он и находит переменную test
со значением 42
, что и выводит в консоль.Сегодня будет #Задачка12 на ваши любимые прототипы:
Что выведется в консоль? А почему?
Ответ на нее будет нескоро, нужно всю бездну затронутых тем хорошенько сжать и компактно описать, так что у вас есть время хорошенько подумать и прислать свой обстоятельный ответ на @djamah
Также не забывайте, что больше, чем хорошим ответам я радуюсь только новым вопросам, их тоже присылайте.
function X() {}
function Y() {}
Y.prototype = Object.create(X.prototype);
var z = new Y();
console.log(z.constructor === Y);
Что выведется в консоль? А почему?
Ответ на нее будет нескоро, нужно всю бездну затронутых тем хорошенько сжать и компактно описать, так что у вас есть время хорошенько подумать и прислать свой обстоятельный ответ на @djamah
Также не забывайте, что больше, чем хорошим ответам я радуюсь только новым вопросам, их тоже присылайте.
#Задачка13 будет скорее философским вопросом:
Вот все мы знаем, что навешивать обработчик события через html-атрибут — это старомодно и вообще плохо, если мы видим код вроде такого:
Мы тут же скривимся и скажем что-то типа: "Что за реликтовая писанина из лихих 90х?.."
Но если мы видим:
То сразу думаем: Это же реакт, клево.
Или:
Все ясно, ангулар — модно, стильно, молодежно.
Мой вопрос собственно в чем: А почему первый вариант это плохо, а остальные это хорошо?
Может ну их, эти фреймворки?
Представьте, что у вас это спросили на собеседовании и попробуйте обстоятельно порассуждать на эту тему.
Лучший из присланных ответов на @djamah я опубликую в среду, а свой вариант озвучу на видео, в котором буду рассказывать про события в js, его вчера как раз записывал, а когда оно выйдет пока не знаю)
Вот все мы знаем, что навешивать обработчик события через html-атрибут — это старомодно и вообще плохо, если мы видим код вроде такого:
<button onclick="alert('oops')">
Click me!
</button>
Мы тут же скривимся и скажем что-то типа: "Что за реликтовая писанина из лихих 90х?.."
Но если мы видим:
<button onClick={() => alert('Wow!')}>
Click me!
</button>
То сразу думаем: Это же реакт, клево.
Или:
<button (click)="alert('Wow!')">
Click me!
</button>
Все ясно, ангулар — модно, стильно, молодежно.
Мой вопрос собственно в чем: А почему первый вариант это плохо, а остальные это хорошо?
Может ну их, эти фреймворки?
Представьте, что у вас это спросили на собеседовании и попробуйте обстоятельно порассуждать на эту тему.
Лучший из присланных ответов на @djamah я опубликую в среду, а свой вариант озвучу на видео, в котором буду рассказывать про события в js, его вчера как раз записывал, а когда оно выйдет пока не знаю)
Лучший, на мой взгляд, ответ к #Задачка13 прислал Евгений, спасибо ему большое:
Проблема с первым вариантом в том, что фронтенд за последнее время сильно усложнился, и подобный код плохо масштабируются.
Действительно, если на странице нужно вывести один алерт при нажатии на кнопку, то инлайновый js прекрасно справится с этой задачей. К сожалению, современные веб-приложения немного сложнее.
Backbone, Angular, React и т.п. рождаются тогда, когда появляется боль. Когда добавление микрофичи требует десятки часов. Когда накопившийся технический долг вот-вот расплющит тебя, команду и проект. Когда ты пытаешься понять тот момент, где ты свернул не туда.
При внешнем сходстве в задаче представлены совершенно разные подходы. Инлайновый js не инкапсулирован, не масштабируем, загрязняет глобальную область видимости.
React/angular/vue-стиль, напротив, помогает справляться со сложностью. Все необходимые обработчики инкапсулированы внутри компонентов. Из компонентов как из лего можно собирать конструкции любой сложности, и разработка из ада, выжигающего твою душу, превращается в приятное времяпровождение.
Проблема с первым вариантом в том, что фронтенд за последнее время сильно усложнился, и подобный код плохо масштабируются.
Действительно, если на странице нужно вывести один алерт при нажатии на кнопку, то инлайновый js прекрасно справится с этой задачей. К сожалению, современные веб-приложения немного сложнее.
Backbone, Angular, React и т.п. рождаются тогда, когда появляется боль. Когда добавление микрофичи требует десятки часов. Когда накопившийся технический долг вот-вот расплющит тебя, команду и проект. Когда ты пытаешься понять тот момент, где ты свернул не туда.
При внешнем сходстве в задаче представлены совершенно разные подходы. Инлайновый js не инкапсулирован, не масштабируем, загрязняет глобальную область видимости.
React/angular/vue-стиль, напротив, помогает справляться со сложностью. Все необходимые обработчики инкапсулированы внутри компонентов. Из компонентов как из лего можно собирать конструкции любой сложности, и разработка из ада, выжигающего твою душу, превращается в приятное времяпровождение.
#Задачка14
А осилите старую добрую...
Что выведется в консоль? Почему?
А осилите старую добрую...
(function(){
return [2,2,2,2].map(parseInt)
})()
Что выведется в консоль? Почему?
Самый полный разбор #Задачка14 прислал Игорь, спасибо ему!
Публикую с минимальными редакторскими правками:
===
Мораль такова, что вызывать функции нужно с _явным_ указанием параметров, а не абы как.
При вызове в функцию
пруф — https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/map
А у глобального метода
пруф — https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/parseInt
В данном примере происходит вызов метода
В итоге:
Думаю, что задача не на знание специфики JS и его версий, а на культуру кода:
за использование кода, приведенного в задаче, нужно расстреливать из рогаток на месте. Никаких сокращений, только явно указанные параметры функций.
===
От себя добавлю, что любой психодел, который вам встречается где бы то ни было, это всегда отличный повод заглянуть в спецификацию, ну не подряд же ее читать в конце-то концов))
А если вам все равно непонятно, можно посмотреть мой разбор этой задачки на видео (я там разжевываю), ссылка на нужную минуту:
https://youtu.be/ncaWoyLINoI?t=26m25s
Публикую с минимальными редакторскими правками:
===
Мораль такова, что вызывать функции нужно с _явным_ указанием параметров, а не абы как.
При вызове в функцию
Array.map
передаются следующие параметры:currentValue, index, array
пруф — https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/map
А у глобального метода
parseInt
два параметра:string, radix
- причем radix
является обязательным параметром, если его не указывать возможны непредсказуемые результатыпруф — https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/parseInt
В данном примере происходит вызов метода
parseInt
с аргументами из функции Array.map
:parseInt(currentValue, index)
, где index
: 0, 1, 2, 3
В итоге:
radix = 0 - поведение по умолчанию, результат 2 в десятичной системе
radix = 1 - допускается значение radix от 2 до 36, NaN
radix = 2 - для двоичной системы допускаются символы 0, 1 и NaN
radix = 3 - результат 2, но в троичной системе исчисления
Думаю, что задача не на знание специфики JS и его версий, а на культуру кода:
за использование кода, приведенного в задаче, нужно расстреливать из рогаток на месте. Никаких сокращений, только явно указанные параметры функций.
===
От себя добавлю, что любой психодел, который вам встречается где бы то ни было, это всегда отличный повод заглянуть в спецификацию, ну не подряд же ее читать в конце-то концов))
А если вам все равно непонятно, можно посмотреть мой разбор этой задачки на видео (я там разжевываю), ссылка на нужную минуту:
https://youtu.be/ncaWoyLINoI?t=26m25s
MDN Web Docs
Array.prototype.map() - JavaScript | MDN
Метод map() создаёт новый массив с результатом вызова указанной функции для каждого элемента массива.
Народ, а кто что читает в телеграме про фронтенд?
Напишите мне в личку на @djamah, ну кроме @forwebdev только, его то и так ясно, что все читают)
Напишите мне в личку на @djamah, ну кроме @forwebdev только, его то и так ясно, что все читают)
#Задачка15 — простите, многобукв, но весело же)
Допустим вы собеседуетесь на позицию, на которой вам предстоит не только код писать, но и менторить совсем зеленых джунов. И для этого абстрактного джуна была задача:
Сделать квадрат, который по клику меняет цвет (серый -> синий -> зеленый -> желтый).
Все по идее просто и понятно, а присылают вам такой (работающий!) код:
Со стилями и разметкой вроде бы все ок (никакого БЭМа в условии задачи не было), но вот с js есть проблемка...
Присылайте на @djamah текст назидательного разьяснения, которое бы вы написали в ответ на эту работу, где вы с высоты своей мудрости коротко и ясно объясняете в чем проблема, почему так делать нельзя и как нужно.
p.s. На следующей неделе я опубликую разбор от автора кода)
Допустим вы собеседуетесь на позицию, на которой вам предстоит не только код писать, но и менторить совсем зеленых джунов. И для этого абстрактного джуна была задача:
Сделать квадрат, который по клику меняет цвет (серый -> синий -> зеленый -> желтый).
Все по идее просто и понятно, а присылают вам такой (работающий!) код:
<style>
.sq {
width: 100px;
height: 100px;
margin: 15px;
background-color: gray;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
.green {
background-color: green;
}
</style>
<div class="sq"></div>
<script>
var $sq = document.querySelector('.sq');
$sq.addEventListener('click', function() {
this.classList.toggle('blue');
this.addEventListener('click', function() {
this.classList.toggle('yellow');
this.addEventListener('click', function() {
this.classList.toggle('green');
});
});
});
</script>
Со стилями и разметкой вроде бы все ок (никакого БЭМа в условии задачи не было), но вот с js есть проблемка...
Присылайте на @djamah текст назидательного разьяснения, которое бы вы написали в ответ на эту работу, где вы с высоты своей мудрости коротко и ясно объясняете в чем проблема, почему так делать нельзя и как нужно.
p.s. На следующей неделе я опубликую разбор от автора кода)
Forwarded from Заметки Андрея Романова
На собеседованиях иногда просят назвать способы отправки запроса на сервер. Помимо очевидных fetch/XMLHttpRequest и прочих джаваскриптовых штук есть более экзотические способы вроде
Вчера узнал о ещё более экзотическом и извращённом способе отправки запроса на сервер с помощью CSS:
Этот способ может использоваться для аналитики и трекинга пользователей, у которых отключен JS. Можно отследить клики по ссылкам, ввод текста в инпуты, клики по чекбоксам, длительность ховера на каком-либо элементе; также можно приблизительно определить браузер и операционную систему пользователя. Подробности — https://github.com/jbtronics/CrookedStyleSheets
Защититься от этого можно только отключив CSS. Параноикам пора переходить на текстовые браузеры :–)
<img src="...">
.Вчера узнал о ещё более экзотическом и извращённом способе отправки запроса на сервер с помощью CSS:
body::after {
content: url('...');
}
Этот способ может использоваться для аналитики и трекинга пользователей, у которых отключен JS. Можно отследить клики по ссылкам, ввод текста в инпуты, клики по чекбоксам, длительность ховера на каком-либо элементе; также можно приблизительно определить браузер и операционную систему пользователя. Подробности — https://github.com/jbtronics/CrookedStyleSheets
Защититься от этого можно только отключив CSS. Параноикам пора переходить на текстовые браузеры :–)
GitHub
GitHub - jbtronics/CrookedStyleSheets: Webpage tracking only using CSS (and no JS)
Webpage tracking only using CSS (and no JS). Contribute to jbtronics/CrookedStyleSheets development by creating an account on GitHub.
Кстати, вот канал (@andrew_r_notes) с которого я перепостил прошлое сообщение очень клевый блог разработчика, в котором есть как крутые истории из разработческой жизни так и небольшие разборы разных аспектов фронтендерских технологий.
Ведет его Андрей Романов, автор того самого @forwebdev на котором много клевых ссылок всегда
Ведет его Андрей Романов, автор того самого @forwebdev на котором много клевых ссылок всегда
Спасибо всем кто присылал ответы на #Задачка15, особенно Игорю
А вообще, код который был в задаче прислала мне когда-то Катя как ответ на домашнее задание, она же и сделала разбор своих былых ошибок.
Текста много, потому гист — https://gist.github.com/katfastovets/95c873d06c45a9756cae3f8ab1eebc55
А вообще, код который был в задаче прислала мне когда-то Катя как ответ на домашнее задание, она же и сделала разбор своих былых ошибок.
Текста много, потому гист — https://gist.github.com/katfastovets/95c873d06c45a9756cae3f8ab1eebc55
Gist
Разбор задачки про события
Разбор задачки про события. GitHub Gist: instantly share code, notes, and snippets.
Сегодня наконец вышло видео, в котором я рассказываю о DOM-событиях.
Само собой, это лучше видео по теме)
Сняли его мы полтора месяца назад, а потом я долго тупил)
В самом видео я много гакаю и эээкаю, все как вы любите.
https://youtu.be/Sczl4lT7huk
Пишите комменты, если понравилось, или не понравилось, ставьте лайки и дизлайки, подписывайтесь на канал)) Это все влияет на то, что ютуб покажет видео большему количеству людей, а мне это важно.
P. S. В конце видео мой ответ на #Задачка13
* в видео есть одна несостыковка, кто заметил — молодец
Само собой, это лучше видео по теме)
Сняли его мы полтора месяца назад, а потом я долго тупил)
В самом видео я много гакаю и эээкаю, все как вы любите.
https://youtu.be/Sczl4lT7huk
Пишите комменты, если понравилось, или не понравилось, ставьте лайки и дизлайки, подписывайтесь на канал)) Это все влияет на то, что ютуб покажет видео большему количеству людей, а мне это важно.
P. S. В конце видео мой ответ на #Задачка13
* в видео есть одна несостыковка, кто заметил — молодец
YouTube
Front-end || DOM-события в трех актах | Юрий Федоренко
Рассказ обо всем, что нужно знать о DOM-событиях.
Не бывает собеседований на должность Front-end-специалиста, где не спрашивают о Document Object Model событиях.
В этом видео все разложено по полочкам:
00:00 — Вступление
0:29 — Почему события в Javascript…
Не бывает собеседований на должность Front-end-специалиста, где не спрашивают о Document Object Model событиях.
В этом видео все разложено по полочкам:
00:00 — Вступление
0:29 — Почему события в Javascript…