Обновить
223.82

JavaScript *

Прототипно-ориентированный язык программирования

Сначала показывать
Порог рейтинга

Как немножко хакнуть Мосрег⁠⁠

Всем привет!

При оформлении заявлений в детский сад на детей на uslugi.mosreg.ru столкнулся с тем, что если ранее было подано заявление и нужно какие-то данные в нём поправить, то выбрать год зачисления ребёнка в ДС можно только следующий. То есть, мы подали в 2024, а теперь можно выбрать только 2026 год, потому что текущий нельзя.

Мне показалось это не очень удобным, решил немножко изучить фронтенд сайта и обнаружил, что валидации на простановку года нет :)

В видео подробнее, как обойти ограничение

P.S. На записи не видно контекстного меню в браузере, когда нажимаешь ПКМ, нас интересует последний пункт "Просмотреть код"

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии2

Сила RxJS. scan + mergeScan = 'Загрузить еще'

Кнопка 'Загрузить еще' (либо автоматическая подгрузка данных при скролле) довольно часто встречается в проектах и обычно решение связано с большим количеством подписок и переменных.

Как всегда, для оптимизации чего либо нам на помощь приходит великий и могучий RxJS, а в данной ситуации конкретно операторы scan & mergeScan.

Код:

  readonly loadTrigger$ = new Subject<void>();
  private readonly batchSize = 5;

  private readonly posts$ = this.loadTrigger$.pipe(
    startWith(void 0),
    scan((offset) => offset + this.batchSize, -this.batchSize),
    mergeScan(
      (accPosts: Post[], offset: number) =>
        getPosts(offset, this.batchSize).pipe(
          map((newPosts) => [...accPosts, ...newPosts]),
        ),
      [] as Post[],
    ),
  );
  1. scan – калькулятор + хранитель состояния для offset:

    • Управляет состоянием загрузки (текущее смещение)

    • Начинается с -batchSize, чтобы первая загрузка была с 0

    • Увеличивает смещение на batchSize при каждом срабатывании

  2. mergeScan – волшебный оператор для инкрементальной загрузки:

    • Сохраняет массив накопленных постов

    • Объединяет новые данные с существующими

    • Корректно обрабатывает параллельные запросы (в отличие от обычного scan)

Где полезен этот паттерн?

  • Постраничные API (пагинация)

  • Бесконечная прокрутка

  • Порционная загрузка данных

  • Любые сценарии накопления асинхронных данных

scan - https://rxjs.dev/api/operators/scan
mergeScan - https://rxjs.dev/api/operators/mergeScan
Больше об Angular - https://t.me/grandgular

Теги:
Рейтинг0
Комментарии0

Я сделал таймер Pomodoro с котами

Привет, ребята!
Я создал небольшой сторонний проект — милый маленький таймер Pomodoro с котами под названием Meowdoro.

Это бесплатное расширение Chrome, которое помогает вам оставаться сосредоточенным с помощью техники Pomodoro.

Вы можете настраивать сеансы работы/перерыва, отслеживать свою статистику и даже соревноваться в простой таблице лидеров.
О, и есть кот, который мурлычет, когда наступает время перерыва.

Ничего особенного — просто то, что я хотел для себя и решил поделиться.
Буду рад любым конструктивным отзывам или идеям по улучшению!

https://chromewebstore.google.com/detail/meowdoro-tracker-pomodoro/gmmcoggmjnbbklphjcbnpfepmagelgkk

Спасибо за чтение! 😺

Теги:
Всего голосов 4: ↑4 и ↓0+4
Комментарии5

МойОфис Frontend&UX Talks уже начался!

Самое время смотреть и задавать вопросы спикерам в чате митапа!

Митап посвящен главным вызовам и проблемам в сложных интерфейсах. Спикеры расскажут о самых разных аспектах фротенда в 2025 году: от айтрекинга и других методов исследований до реактивного программирования и СSS-спецификаций.

Сам митап разделен на две категории: JavaScript и UX. В каждой из них, помимо наших специалистов, есть ребята и из других компаний: Лаборатория Касперского, Контур, Alpha Research Center. Всего на встрече будет семь докладов – их расписание можно посмотреть здесь.

Смотрите митап прямо здесь:

Также трансляцию можно смотреть на Youtube и ВК.

Заинтересовало? Тогда скорее переходите в чат митапа. Здесь можно задать вопросы спикерам, и получить раньше остальных доступ к записи выступлений :)

Теги:
Всего голосов 14: ↑14 и ↓0+14
Комментарии0

Как студенты с айтрекером изучали наш текстовый редактор

Июнь стал месяцем айтрекинга в UX-команде МойОфис. Сначала у нас прошло совместное исследование со студентами ВШЭ, а в ближайшие дни мы проведем крупный митап, где поговорим о создании и анализе сложных интерфейсов, в том числе с помощью технологий отслеживания взгляда.

Важный анонс: 26 июня пройдет онлайн-митап МойОфис Frontend&UX Talks, на котором JS-еры, дизайнеры, продакты и аналитики соберутся, чтобы обсудить все насущные проблемы и нюансы современного фронтенда. Кроме наших экспертов, на митапе будут ребята из Лаборатории Касперского, Контура и Alfa Research Center!

Регистрируемся и читаем темы выступлений здесь – и вступаем в чат, чтобы не пропустить важные обновления (и просто поболтать с коллегами по фронтендерскому цеху).

Еще немного о совместном исследовании со студентами:

4 июня в нашем петербургском офисе прошла презентация результатов совместного исследования с лабораторией социальной и когнитивной информатики ВШЭ в рамках учебного сотрудничества. Студенты курса «Айтрекинг в UX-аналитике» провели глубокое тестирование текстового редактора МойОфис 3.4 с обновлённым интерфейсом.

Методология:

  • Определили самые востребованные задачи у студентов и на их основе составили задания.

  • Использовали носимый open-source айтрекер PupilLabs.

  • Провели психологические опросы до и после заданий (спойлер: уровень стресса участников не изменился) и когнитивное интервью после.

Ключевые результаты:

  1. Проявилась часть проблем, о которых мы уже знали и исправили в версии редактора 3.5. Например, более удобное выделение ячеек таблицы без лишнего клика.

  2. Получили оценки пользователей: лёгкость и чёткость интерфейса.

  3. Подтвердилась необходимость в новом поиске по функциям, к которому прибегали участники, когда что-то не получалось найти, или они не знали, как выполнить задачу.

  4. Выявлены новые точки роста для развития продукта

P.S. Большая благодарность Елене Артёменко из лаборатории социальной и когнитивной информатики ВШЭ за эту коллаборацию! А если хотите узнать больше о фронтенде и UX-исследованиях — ждем вас 26 июня на Frontend&UXTalks!

Теги:
Всего голосов 16: ↑16 и ↓0+17
Комментарии2

afterEveryRender и afterNextRender

В Angular 20 afterRender был переименован в afterEveryRender, и это очень логично, так как теперь он более четко отражает суть (нейминг решает). Сам afterRender (далее afterEveryRender) и его брат afterNextRender появились в версии 17. Рассмотрим, почему эти два мощных инструмента управления рендерингом — не просто альтернативы ngAfterViewInit, а полноценные хуки жизненного цикла с бесшовной поддержкой SSR!

Это хуки?
Да! Это хуки нового типа, которые выполняются после рендеринга компонента:

  • Они не заменяют ngAfterViewInit/ngAfterContentInit, а дополняют их

  • Включают гранулярные реакции на рендеры, включая обновления

Почему идеально подходит для SSR?
Главное преимущество: обратные вызовы выполняются только на клиенте!
✅ После гидратации (в SSR)
✅ После первоначального рендеринга (в CSR)
✅ Больше никаких ошибок «документ не определен»

Использование:
constructor() {
// 🚫 Не запускается на сервере
// ✅ Запускается только один раз после загрузки браузера!
// 📊 Идеально подходит для однократной инициализации
afterNextRender(() => {
console.log('Next');
});

// 🚫 Не запускается на сервере
// 🔄 Запускается после каждого цикла обнаружения изменений
// ✨ Отлично подходит для обновлений, зависящих от DOM
afterEveryRender(() => {
console.log('Every');
});
}


Когда использовать?

afterNextRender

  • Одноразовые операции (инициализация библиотеки, загрузка данных)

  • Безопасная замена ngAfterViewInit для SSR

afterEveryRender

  • Отслеживание изменений DOM (измерения элементов, позиции)

    ⚠️ Внимание: может повлиять на производительность

Основные выводы

  • Интегрировано в систему жизненного цикла Angular

  • Автоматический пропуск на стороне сервера - больше никаких хаков isPlatformBrowser!

  • afterNextRender - "один раз после рендеринга"

  • afterEveryRender - "после каждого обновления"

"Я пока не использовал afterEveryRender в своих проектах - есть ли у вас практические примеры использования? Поделитесь в комментариях!"

Больше об 🅰️ngular в моём Telegram-канале

Теги:
Рейтинг0
Комментарии0

JavaScript, дизайн-системы и рок-н-ролл — что такое фронтенд в 2025 году? 

Что происходит, когда в одном месте собираются JS-еры, UX-дизайнеры и исследователи? Получается Frontend&UX Talks!

Без сложных интерфейсов в фронтенде сегодня никуда: продукты становятся все масштабнее, а требования – все выше. Для всего этого нужны свежие и эффективные решения, которые ускорят разработку, и помогут провести релевантные UX-исследования.

Чтобы обсудить эти темы, мы в МойОфис пригласили ребят из разных компаний: Alfa Research Center, Лаборатория Касперского и Контур.

Всего на митапе будет 7 докладов, где расскажем:

  • как реактивное программирование и RxJS меняет разработку – и какие у него есть нюансы;

  • какие свежие css-спецификации могут упростить ежедневный кодинг;

  • как «редизайнить» сложные интерфейсы: рассказ на личном опыте переосмысления визуала настольных редакторов практически с нуля;

  • что за методы UX-исследований использует финтех сегодня – и какие из них можете перенять и вы :)

и многое другое, что поможет в работе со сложными интерфейсами!

Если тебе близки эти темы — приходи 26 июня в 15:00. Регистрация и подробности по ссылке.

Теги:
Всего голосов 15: ↑15 и ↓0+15
Комментарии0

withComponentInputBinding()
Упрощение работы с параметрами маршрутизатора в Angular.

Как было раньше?

  1. Создаем переменную/свойство (Signal, BehaivorSubject, Observable, неважно)

  2. Инжектим и подписываемся на ActivatedRoute

  3. Получаем параметры маршрута

  4. Записываем в BS/Signal

😵‍💫😵‍💫😵‍💫

Манипуляций довольно много, но мы все к этому привыкли и это кажется нормальным.

Но с withComponentInputBinding() все стало намного проще:
1. Создаем сигнальный инпут... и...
Вот и все!

Никаких дополнительных манипуляций, и значение «у вас в кармане». Все, что вам нужно, чтобы это работало, — это передать withComponentInputBinding() в качестве аргумента в provideRouter().

Функция не новая (кажется, появилась в Angular 16), но я редко ее видел в проектах.

Немного технической информации из документации:

🔍Маршрутизатор передает данные в input() из:

  1. Параметров запроса (?page=1&sort=asc)

  2. Параметров пути и матрицы (/users/123;details=true)

  3. Статических данных маршрута (data: { role: 'admin' })

  4. Результатов резолвера (resolve: { user: userResolver })

🔍 Приоритеты:
Если есть дублирующиеся ключи, данные переопределяются в порядке выше — резолверы имеют наивысший приоритет и перезапишут остальные.

🚩 Важный нюанс
Если в маршруте нет данных для input(), он получит undefined (например, если параметр запроса удален из URL).

ℹ️ Как задать значения по умолчанию?

✔ Через resolver (чтобы данные всегда были в маршруте)
✔ Через transform в input() (если нужно обрабатывать undefined)

Спасибо разработчикам Angular за эту функциональность 🙏.

Больше об 🅰️ngular в моём Telegram-канале

Теги:
Всего голосов 2: ↑1 и ↓1+2
Комментарии0

Что происходит с JavaScript-кодом внутри V8?

Сначала любая программа подвергается лексическому анализу, который выполняет компонент V8 под названием Scanner. И он разбивает исходный код на поток отдельных токенов в соответствии с лексической грамматикой, описанной в спецификации ECMAScript.

Интересно, что невалидные программы, вроде...

const = = ;

...ещё не выдадут ошибку на данном этапе. Сканер спокойно разобьет нашу программу на токены и отдаст дальше, ведь проверка синтаксической корректности не его зона ответственности. Это зона ответственности Parser, который способен выявить все синтаксические ошибки.

Кстати, одна из ключевых особенностей Parser — генерация Abstract Syntax Tree, которое затем используется для создания байт-кода внутри Ignition. На основе полученных токенов из Scanner генерируется дерево, в котором каждый узел отражает языковую конструкцию: идентификатор, оператор, выражение или функцию.

Например, для кода...

const sum = (a, b) => a + b;

...мы получим следующее дерево:

VariableDeclaration (const)└── VariableDeclarator    ├── Identifier: sum    └── ArrowFunctionExpression        ├── Params        │   ├── Identifier: a        │   └── Identifier: b        └── BinaryExpression (+)            ├── Identifier: a            └── Identifier: b

Об остальном, что происходит на этапах лексического анализа и синтаксического анализа в V8, читайте в статье «Что происходит с вашим JavaScript-кодом внутри V8. Часть 1».

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии1

Я устал от форматирования JSON файлов

Я много и часто просматриваю JSON-файлы: от конфигураций сервисов до API ответов и логов. Каждый раз, открывая очередной файл, я форматирую содержимое, чтобы было удобнее читать (ведь JSON не только machine-readable, но и human-readable). И каждый раз я грущу, что все сервисы (онлайн, встроенные средства IDE и даже плагины) предоставляют лишь две крайности: форматировать всё или ничего (минифицировать в одну строку).

Но что, если я хочу отформатировать JSON лишь до определённого уровня? Что, если у меня есть огромный список словарей (возможно, даже глубоких), который при форматировании выглядит как-то так:

[
    {
        "id": 1,
        "name": "Alice",
        "birthday": {
            "day": 5,
            "month": 4,
            "year": 1983
        }
    },
    {
        "id": 2,
        "name": "Bob",
        "birthday": {
            "day": 6,
            "month": 2,
            "year": 1945
        }
    },
    {
        "id": 3,
        "name": "Eve",
        "birthday": {
            "day": 10,
            "month": 11,
            "year": 1978
        }
    }
]

Что, если я хочу оставить каждый словарь в более компактном (не совсем минифицированном) виде? Например, таком:

[
    {"id": 1, "name": "Alice", "birthday": {"day": 5, "month": 4, "year": 1983}},
    {"id": 2, "name": "Bob", "birthday": {"day": 6, "month": 2, "year": 1945}},
    {"id": 3, "name": "Eve", "birthday": {"day": 10, "month": 11, "year": 1978}}
]

Или я хочу, чтобы в каждом словаре развёрнуты были только внешние ключи?

[
    {
        "id": 1,
        "name": "Alice",
        "birthday": {"day": 5, "month": 4, "year": 1983}
    },
    {
        "id": 2,
        "name": "Bob",
        "birthday": {"day": 6, "month": 2, "year": 1945}
    },
    {
        "id": 3,
        "name": "Eve",
        "birthday": {"day": 10, "month": 11, "year": 1978}
    }
]

Да, многие текстовые редакторы вроде Sublime Text или VS Code дают возможность свернуть контент до определённого уровня. Но что, если я хочу оставить файл в этом промежуточном виде и просматривать его прямо в терминале, подключившись по ssh? Или я хочу посмотреть файл на гитхабе с телефона? Да, возможно, мои вкусы весьма специфичны, но в существующих реалиях я вынужден грустно довольствоваться лишь полностью развёрнутым вариантом (или делать это вручную). Встроенные средства форматирования JSON в JS или Python также не предоставляют простой возможности ограничить глубину (либо я так и не научился их готовить).

Поэтому я собрался с силами и написал свой форматтер с возможностью ограничить глубину. Помимо базового функционала вроде валидации, минификации и настройки количества отступов, в нём есть настройка максимальной глубины (по умолчанию она равна нулю, что соответствует привычному форматированию без ограничений).

Да, он вряд ли подойдёт, чтобы редактировать на лету гигантские JSON файлы. И он уж точно не пытается стать убийцей какого-либо из существующих онлайн сервисов. В первую очередь он призван решить мою проблему: сделать форматирование JSON чуточку более управляемым. А если и вы сталкивались с подобной проблемой, буду рад, если сервис поможет и вам!

Теги:
Всего голосов 7: ↑7 и ↓0+7
Комментарии0

Angular Hack: Цикл без данных (в тэмплейте)

Иногда нужно отобразить несколько одинаковых элементов чисто для ui-целей: скелетоны загрузки, звёзды рейтинга, пустые таблицы и т.д., но без реальных данных для итерации.

Вот мой способ (по крайней мере, я нигде такого не видел):

@for (_ of [].constructor(10); track $index) {
<div class="item"></div>
}

Используется Array.constructor, чтобы создать пустую массив фиксированной длины, который @for может перебрать по индексам.

Плюсы ✅

  • Чудо-код (удивит коллег)

  • Минимум кода (не нужно объявлять массив в компоненте)

Минусы ⚠️

  • Чудо-код (может ненадолго ввести в ступор чающего код человека)

Конечно, можно просто использовать Array.from({length: 10})... но так все делают, не интересно)

Норм тема? Как считаете?

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии3

Приглашаем вас на бесплатный вебинар «TypeScript за час: основы, плюсы и практика». Познакомим вас с TypeScript. Расскажем, зачем он появился, в чём его преимущества и как он помогает писать понятный и надёжный код. Подойдёт и новичкам, и практикам.

⁉️ На вебинаре вы сможете задать вопросы спикеру.

📅 Дата: 13.05.2025

Время: 17:00-18:00 (Мск)

На вебинаре:

✔️ История возникновения TypeScript

✔️ Преимущества использования TypeScript

✔️ Пример написания кода на TypeScript

👨‍🎓 Спикер: Кучин Евгений — разработчик на Java и JavaScript.

✍️Записаться на вебинар

Возможно, вам будет интересен курс «Язык программирования TypeScript». Вы освоите TypeScript, изучив типизацию, интерфейсы и классы. Узнаете, как использовать статическую типизацию, интегрировать TypeScript с существующим JavaScript и настраивать окружение разработки. Это поможет сделать ваш код более безопасным и структурированным.

Старт: 19 мая

Цена: 14 900 8 940 ₽ (-40%)

✍️ Записаться на курс

Теги:
Всего голосов 3: ↑1 и ↓2+1
Комментарии0

Когда нельзя доверять даже себе

Экосистема JavaScript — обширная, гибкая и насыщенная готовыми решениями. Она позволяет без особых усилий подключать сторонние пакеты — как в браузере, так и на сервере. Но у этой открытости есть и обратная сторона: сторонний код может вмешиваться в ваш собственный. Хорошо, если это происходит явно. Но бывает иначе: кто-то оборачивает ваши функции, переопределяет методы, расширяет прототипы — и тихо выполняет свою «чёрную работу».

В такой среде доверие к собственному коду становится условным. Разработчик ещё способен более-менее контролировать точку входа — HTML-страницу или Node.js-скрипт. Он может доверять тому, что написал сам и вызывает сам. До тех пор, пока не подключит стороннюю библиотеку. А дальше — возможны любые сценарии.

Чтобы можно было доверять своему коду хоть немного больше, я пошёл на эксперимент и по умолчанию встроил "заморозку" всех объектов, создаваемых моим DI-контейнером:

let res = await _composer.create(key, module, stack, this);
if (canBeFrozen(res)) Object.freeze(res);

При запуске node-приложения (или при загрузке кода на веб-страницу) я создаю контейнер и через него получаю нужный объект со всеми зависимостями:

import Container from '@teqfw/di';

const container = new Container();
const resolver = container.getResolver();
resolver.addNamespaceRoot('App_', '/home/user/project/src');
const app = await container.get('App_Main');
app.run();

Поскольку все объекты, получаемые из контейнера, автоматически замораживаются, сторонний код не может изменить поведение уже созданной зависимости — даже если получит к ней доступ.

Разумеется, такой подход не делает JS-среду абсолютно безопасной. Но он позволяет немного повысить уровень доверия к тому, что происходит внутри.

Эта идея родилась после прений с коллегой @nin-jin — так что спасибо ему за подброшенную мысль ;) Я реализовал её в коде, опробовал на своих приложениях и вот теперь делюсь результатом.

Теги:
Всего голосов 3: ↑2 и ↓1+2
Комментарии7

Ближайшие события

Опубликовано исследование о том что индексирование сайтов поисковиком (Google) не зависит от того, SPA ли это или же он SSR. Также пару лет назад делал аналогичное расследование и пришел к тому же выводу.

Вообще, мы пришли к идеалу достаточно давно - когда сервер занимается своими делами, а клиент статический, минифицирован, и раздается из CDN для быстроты и без траты ресурсов сервера.

https://vercel.com/blog/how-google-handles-javascript-throughout-the-indexing-process

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии9

ИИ-ассистенты (промпты) - это тоже low-code. Бизнес-аналитики сами разрабатывают ИТ-продукты. Сайт какой сложности можно разработать без знания JavaScript? Кейс app.2lead.ru

Возможности low-code растут. Бизнес-аналитики сами разрабатывают ИТ-продукты, фактически добавляя к своим обязанностям часть функций программистов. При этом эксперты не прогнозируют, что low-code полностью заменит традиционное программирование в ближайшие годы.

ИИ-помощники (промпты) - это тоже low-code

Чаще всего low-code определяют как создание ПО с помощью графических интерфейсов и настроек, а не через традиционное программирование. Мне ближе более широкое определение: low-code – это системы и платформы, которые предполагают изменение, дополнение кода пользователем, в том числе с применением ИИ-помощников (промптов).

Кейс: Сервисы app.2lead.ru разработаны бизнес-аналитиком

ИИ-ассистенты значительно ускорили разработку сервисов app.2lead.ru, созданных мной на JavaScript - без опыта программирования на этом языке. Это подтверждает возможность разработки ПО силами бизнес-аналитиков, продуктовых менеджеров и так далее. Ранее это была прерогатива только профессиональных программистов. 

Сервисы app.2lead.ru разработаны в конце 2024 года – начале 2025 года. Вошли в топ-5 Яндекса по запросу «калькулятор инфляции». Уже увеличили органический трафик сайта 2lead.ru более чем в 5 раз, без расходов на рекламу. // См. также «Нерекламные методы продвижения» https://habr.com/ru/articles/686736/

Сервисы app.2lead.ru // Калькуляторы инфляции. Аналитика. Прогнозы
Сервисы app.2lead.ru // Калькуляторы инфляции. Аналитика. Прогнозы

Что дальше? Массовое применение таких методов разработки ПО, более совершенные low-code системы и программирование голосом? Считаю, что практику low-code нужно расширять, разрабатывать учебные материалы по этому направлению и т.д. В этих инструментах есть большое пространство для развития.

Теги:
Всего голосов 4: ↑0 и ↓4-4
Комментарии0

На картинке — код на JavaScript с ошибкой, который написал специально для Хабра руководитель группы разработки интерфейсов компании «Криптонит» Василий Беляев.

Кто увидел, где ошибка и как её можно решить — пишите в комментариях! А решение этой ошибки оставили под картинкой.

Где здесь ошибка?
Где здесь ошибка?

Если запустим этот код, то получим ошибку

Uncaught TypeError: this.clearHistory is not a function

Проблема находится на строчках 11-13 (на картинке)

this.timeout = setTimeout (function () {
        this.clearHistory();
    }, 0);

Когда мы вызываем setTimeout, то вызываем метод объекта window, и меняем область видимости с нашего конструктора на window ( window.setTimeout() ).

Именно по этой причине у нас метод clearHistory пытается вызываться у объекта window ( window.clearHistory() )

Как можно решить эту проблему?

Вариант 1

const MyItem = function () {
    this.clearStorage = function () {
        console.log ('Очищаем хранилища...');
    };
    this.clearHistory = function () {
        console.log ('Очищаем историю...');
    };
};
MyItem.prototype.refresh = function () {
    this.clearStorage();
    this.timeout = setTimeout (() => {
        this.clearHistory();
    }, 0);
};
const mуItem = new MyItem();
mуItem.refresh();

Заменить анонимную функцию на стрелочную функцию. У них отсутствует свой контекст, и они работают в контексте области видимости, включающий их самих.

Вариант 2

const MyItem = function () {
    this.clearStorage = function () {
        console.log ('Очищаем хранилища...');
    };
    this.clearHistory = function () {
        console.log ('Очищаем историю...');
    };
};
MyItem.prototype.refresh = function () {
    this.clearStorage();
    this.timeout = setTimeout (
        this.clearHistory.bind(this), 0
    );
};
const mуItem = new MyItem();
mуItem.refresh();

Явно передать контекст через метод .bind()

Вариант 3

const MyItem = function () {
    this.clearStorage = function () {
        console.log ('Очищаем хранилища...');
    };
    this.clearHistory = function () {
        console.log ('Очищаем историю...');
    };
};
MyItem.prototype.refresh = function () {
    this.clearStorage();
    const self = this;
    this.timeout = setTimeout (() => {
        self.clearHistory();
    }, 0);
};
const mуItem = new MyItem();
mуItem.refresh();

Выносим контекст в отдельную переменную и работаем с ней. Этот вариант подойдет для поддержки старых браузеров.

А как бы вы решили эту ошибку?

Теги:
Всего голосов 6: ↑3 и ↓3+2
Комментарии5

Регулярно на Хабре выходят статьи с рекомендацией использовать moment.js. В комментариях обязательно начинают советовать какой-нибудь dayjs или js-joda, но не потому, что они чем-то сильно лучше, а потому, что первый задепрекейчен авторами.. в пользу luxon.

Что за мания такая у JS-еров использовать раздутые тормозные библиотеки? Есть же быстрый и миниатюрный $mol_time с гораздо более удобным и функциональным API, почти полностью поддерживающим ISO8601, в отличие от всех остальных библиотек.

Бенчмарки говорят сами за себя
Бенчмарки говорят сами за себя

Что мотивирует людей довольствоваться не самым лучшим решением в индустрии? Я, наверно, странный, но я не могу этого понять.

Теги:
Всего голосов 18: ↑7 и ↓11-2
Комментарии39

Полезные ресурсы для начинающего JavaScript-разработчика

Делимся полезными материалами, которые помогут разобраться в основах и сделать первые шаги в программировании на JavaScript. 

«Зачем учить JavaScript» — объясняем на примерах, почему без JavaScript не будет современных сайтов и что делает этот язык программирования таким востребованным. Расскажем о преимуществах JS и его перспективах.

«Полезные ресурсы для начинающего разработчика JavaScript» — делимся подборкой курсов, статей, каналов и книг, которые помогут развиваться в профессии.

«Что такое TypeScript и чем он отличается от JavaScript» — у главного языка фронтенда JavaScript есть улучшенная версия — TypeScript. Рассказываем, как он работает и чем отличается от старой версии.

«Всё про JavaScript» — большая подборка статей про основы JavaScript, возможности его использования и типичные ошибки новичков. Также в подборке можно найти задачи для собеседований и туториалы разных проектов.

Теория — это хорошо, а для практики подойдёт бесплатная часть курса «Фронтенд-разработчик». В ней вы изучите базовый синтаксис HTML и CSS, попробуете размещать блоки на веб-странице, менять шрифт и цвета, а также напишете с нуля простую программу на JavaScript.

Теги:
Рейтинг0
Комментарии0

Стоит ли идти во фронтенд сейчас? Честный ответ разработчика

Артем несколько лет в сфере (вот его история). Сейчас он разработчик в крупном финтех-проекте. Вот его мысли:

— Да, фронтенд перенасыщен. Фреймворков много, технологии постоянно меняются. Все говорят об одном, но пишут по-разному. Но именно это и держит в тонусе — приходится регулярно обновлять знания. Сожалею ли я о своем выборе? Нет. Всегда любил погружаться в математические задачи, а фронтенд затягивает. Можно сутки биться над багом, ненавидеть его, плеваться… А потом решить — и словить кайф. В такие моменты код полностью поглощает, заставляя забыть о сне и еде.

Стоит ли идти во фронтенд сейчас?

— Никогда не поздно. Да, путь у каждого свой, и рынок сейчас нестабилен. Но при глубоком погружении за год можно набрать нужные скиллы и попасть на коммерческий проект.

🔥 Открыт набор на новый марафон!

Сейчас в Clevertec проходит марафон для начинающих фронтенд‑разработчиков. Это возможность погрузиться в профессию, получить реальный опыт и, возможно, стать частью команды. Участие бесплатное. Успей зарегистрироваться!

Теги:
Всего голосов 3: ↑1 и ↓2-1
Комментарии1

Запускаем бесплатный онлайн-марафон по фронтенд-разработке. Будет как в «Рокки» 

Спринты, дедлайны и финальный тест-бой. Кто пройдет с нами три месяца подготовки — получит шанс на титул. Без метафор — мы реально ищем таланты и готовы взять их на стажировку.

Как записаться?

Заполни анкету по ссылке в профиле и скинь другу. Заявки принимаем до 26 марта.

Что будет?

Интенсивный 3-месячный тренинг. Это бесплатно. По сути, ты будешь поэтапно с дедлайнами писать приложение. Каждый спринт проверяем с помощью автотестов. Плюс будет поддержка менторов, наших крепких разработчиков. Это реальная прокачка твоих навыков и готовый проект в резюме.

Это уже четвертый марафон — после каждого наша команда фронтенд-разработчиков растет.

Кого ждём?

Начинающих веб-разработчиков (JS, React), которые уже изучали теорию и хотят прокачаться на практике в условиях, максимально близких к реальному проекту. Главное — желание кодить. Подойдут:

- студенты профильных вузов

- выпускники курсов

- самоучки

Важное условие: приглашаем участников из Беларуси и России.

Что дальше?

После 26 марта отправим на почту инструкции и первые задания. Старт марафона 1 апреля (это не шутка). До связи, Рокки. 

Теги:
Всего голосов 4: ↑3 и ↓1+4
Комментарии0

Вклад авторов