Задать вопрос
Ответы пользователя по тегу JavaScript
  • Какое практическое применение для функции генератора?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Генератор - это императивно управляемый итератор. Сами итераторы позволяют производить ленивые вычисления.

    Практическое применение например в том, что можно построить высокоуровневые абстракции над итераторами:
    function* counter() {
      let i = 0;
      while (true) {
        yield i++;
      }
    }
    
    function* map(innerIterator, f) {
      for (const value of innerIterator) {
        yield f(value);
      }
    }
    
    function* filter(innerIterator, f) {
      for (const value of innerIterator) {
        if (f(value)) {
          yield value;
        }
      }
    }
    
    function* take(innerIterator, count) {
      let i = 0;
      for (const value of innerIterator) {
        yield value;
        if (++i === count) { return }
      }
    }
    
    function* inspect(innerIterator) {
      for (const value of innerIterator) {
        console.log(value);
        yield value;
      }
    }
    
    console.log('Создаем итератор');
    const iter = inspect(
      take(
        map(
          filter(
            counter(),
            v => v % 2 === 0
          ),
          v => v * 2
        ),
        30
      )
    );
    console.log('Итератор есть, но он еще ничего не считает: ', iter);
    console.log('Вычисления будут по требованию:');
    console.log([...iter]);
    Ответ написан
  • Чем JavaScript абстрактнее других языков программирования?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    На JS можно спокойно писать (и очень многие пишут) вообще не задумываясь где и как у Вас выделяется память и где и когда она освобождается. И программа будет работать, возможно даже без багов и утечек.

    В JS Вам не нужно думать, о том сколько живут объекты, если у Вас есть ссылка - объект точно жив.

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

    В JS у Вас никогда не будет Undefined Behavior.

    В JS у Вас никогда не будет гонок данных, каждый поток (воркер) живет в своем пространстве памяти. И даже если Вы пошарите память, Вам не придется парится с атомиками/мьютексами и c memory order, все уже решили за Вас.

    В C++ Вам придется об этом всем думать, если захотите написать что-то полезное.
    Ответ написан
    2 комментария
  • Как правильно присвоить класс?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const mediaQuery = window.matchMedia('(max-width: 992px)');
    const handler = () => 
        $(document.body).toggleClass('lock', mediaQuery.matches);
    mediaQuery.addListener(handler);
    handler();

    https://developer.mozilla.org/ru/docs/Web/API/Wind...

    А вообще, такое спокойно через CSS можно делать:
    @media (max-width: 992px) {
        body {
            /* тут то что у Вас в .lock было */
        }
    }
    Ответ написан
    2 комментария
  • Как распарсить readbleStream, чтобы получить из него файл?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://nodejs.org/dist/latest-v14.x/docs/api/stre...
    https://nodejs.org/dist/latest-v14.x/docs/api/stre...

    Но в Вашем примере уже присутствует pipe, который сам вычитывает readable поток в writable (в Вашем случае res)
    https://nodejs.org/dist/latest-v14.x/docs/api/stre...

    Поток штука одноразовая, 2 раза прочитать не получится, благо с обычными файлами никто не мешает открыть любое количество потоков.
    Ответ написан
    Комментировать
  • Как в java script представить строку вида "level1[level2][level3]" в массив/объект/map с соответственной вложенностью?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Придется парсить ключи в обработчике submit:
    const re = /(.+)\[(.+)\]\[(.+)\]/;
    const formData = new FormData(drawingForm);
    const result = {};
    for (const [key, value] of Object.entries(formData)) {
        const matches = key.match(re);
        if (!matches) { continue }
        const [, k1, k2, k3] = matches;
        ((result[k1] ??= {})[k2] ??= {})[k3] = value;
    }
    console.log(result); // тут валидация
    Ответ написан
    1 комментарий
  • Как разобраться с rpc запросами на основе TL-схемы?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ответ написан
    Комментировать
  • Как работает VPAID?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Стандарт VPAID описывает лишь интерфейс взаимодействия плеера с креативом.
    Внутри может быть абсолютно любой код, который может делать все что угодно в рамках своего контекста, в том числе тоже быть плеером, который подгрузит рекламу по VAST/VPAID.

    В VAST могут быть параметры для VPAID, но он не обязан их использовать. Он может сходить за рекламой на свой сервер, который ему заранее известен, или вообще воспроизводить рекламу, которая в него зашита.

    А может и не рекламу крутить, я например как то делал в виде VPAID интерактивную вакансию и таргетировал ее на IT'шников через рекламные сети.
    Ответ написан
    Комментировать
  • Как реализовать цикл на JS?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    У Вас функции popup1, popup2 и popup3 ничего не возвращают
    if (popup1() === random)соответственно здесь строго сравнивается undefined с числом, что всегда даст false.

    Вангуя следующий вопрос, сразу намекну, что prompt возвращает строку, и ее тоже так в лоб с числом не сравнишь.

    Ну и напоследок:if (agreement === true)зачем === true в условии, если agreement всегда типа boolean?
    Ответ написан
    1 комментарий
  • Как вытянуть ключ с обьекта который находится в массиве?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ваша проблема в том, что у Вас массив объектов, а Вы пытаетесь с ним работать как с единственным объектом. Прежде чем работать с объектом, нужно получить ссылку на него из массива, например по индексу.

    Еще одна проблема, хоть она и не относится к вопросу, это то что у Вас присутствует бесполезная работа с localStorage (Вы каждый раз пишите туда новые, никак не зависящие от старых, данные, только ради того чтоб их тут же прочитать), а так же бесполезная сериализация/десериализация JSON.
    Отношение к пользовательским ресурсам - все равно что вломится к пользователю домой и плюнуть ему в лицо.
    Ответ написан
    Комментировать
  • Как сохранять события в localStorage js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    localStorage.getItem сам не поставит класс элементу, он просто читает значение
    if (localStorage.getItem('theme') !== null) {
        localStorage.getItem('theme') // эта строка ничего не делает
    }


    Попробуйте так:
    (function () {
      const blue = document.querySelector('#pink')
    
      switch (localStorage.getItem('theme')) {
          case 'blueTheme':
              blue.classList.add('blueTheme')
      }
    
      blue.addEventListener('click', () => {
        if (blue.classList.contains('blueTheme')) {
            blue.classList.add('blueTheme')
            localStorage.setItem('theme', 'blueTheme')
        } else {
            blue.classList.remove('blueTheme')
            localStorage.removeItem('theme')
        }
      })
    }())
    Ответ написан
    Комментировать
  • В чем разница двух конструкций в js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    $(function() {
    
    });
    вызывает функцию $ и отдает ей анонимную функцию в качестве аргумента

    (function($) {
    
    })(jQuery);
    Вызывает анонимную функцию сразу, параметр jQuery попадет в аргумент $ внутри функции
    Ответ написан
    Комментировать
  • В этом случае объект очищается по причине работы алгоритма Mark-and-sweep или это просто эффект работы локальной переменной...?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Все сильно зависит от движка, но в основном принципы похожи. Расскажу на примере v8 (chrome, node).
    Первое, что надо понять, в v8 сборка мусора основана на поколениях. И в разных поколениях применяются разные алгоритмы. В v8 используется 3 поколения:
    - Молодое (собирается по наполнению (часто), но быстрым упрощенным алгоритмом)
    - Старое (собирается по расписанию (редко), здесь как раз Mark & Sweep)
    - Особое (я не очень про него знаю, здесь очень большие объекты + объекты с прямым доступом из глобального)

    Второе, что нужно понять, все данные доступные из JS v8 хранит на куче, независимо примитив это или js-объект. С точки зрения GC все есть объект, и числа и строки и функции.

    Теперь более подробно про молодое поколение. Его цель - быть быстрым, быстро выделять и освобождать память. Создатели v8 прекрасно знают, что аллокация на куче - крайне затратная операция, поэтому здесь преаллоцированы 2 страницы памяти, которые используются по очереди. Заодно можно получить бонус в работе с процессорным кэшем, за счет того, что здесь "горячие" данные и они лежат рядом, а значит попадут на одну кэш линию. Когда мы создаем новый объект, v8 просто помещает его в конец активной страницы. Если места не хватает происходит быстрая сборка мусора. А еще здесь используется подсчет ссылок (он быстрее), но только для ссылок из старого поколения - если есть хоть 1 такая ссылка - объект живой, а так же живо все его объектное дерево. Так же нельзя "убивать" объект, если на него есть ссылки из стэка. Все остальное "мертвое". Живые объекты переносятся в начало второй страницы памяти (заодно происходит дефрагментация памяти), после чего она становится активной. Если объект пережил 3 таких быстрых сборки, то вместо второй страницы его переносят на старое поколение, при этом происходит аллокация памяти.

    В Вашем примере задействовано только молодое поколение.
    function f() {
        // это мертвый код, после оптимизации f строка вообще не будет память использовать
        let a = 'some text';
    
        // это 2 молодых объекта, на них уже ссылается контекст вызова f, а на него ссылается стэк
        var obj1 = {};
        var obj2 = {};
        obj1.p = obj2; // obj1 references obj2
        obj2.p = obj1; // obj2 references obj1. This creates a cycle.
    
        // при завершении функции стэк перестает ссылаться на контекст вызова
        // контекст вызова умрет при ближайшей GC,
        // а вместе с ним и obj1 и obj2, так как их никто не отметит "живыми"
    }
    f();
    Ответ написан
    Комментировать
  • Как получить промисо-завершающий callback от асинхронной функции?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если правильно понял замысел, то можно как-то так:
    async function test() {
        let savedResolve, sevedReject;
        const promiseForReturn = new Promise((resolve, reject) => {
            // этот колбэк отрабатывает синхронно
            sevedResolve = resolve;
            savedReject = reject;
        });
        // поэтому savedResolve и sevedReject уже доступны здесь
        sevedReject(1);
        return promiseForReturn; // промис возвращаемый test() будет связан с этим и ждать его
    }

    Но лучше с таким все же быть аккуратным
    async function test() {
        let savedResolve, sevedReject;
        const promiseForReturn = new Promise((resolve, reject) => {
            sevedResolve = resolve;
            savedReject = reject;
        });
        // это deadlock
        await promiseForReturn;
        sevedResolve(1);
    }
    Ответ написан
  • Есть кастомный вариант fullpage js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Для чего нужны getters и setters в JavaScript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Геттеры и сеттеры позволяют навешивать логику на чтение и запись свойств.

    Например фреймворк Vue реализует через них реактивность. В геттере он сохраняет для свойства информацию, кто его читал, можно сказать, что свойство так "понимает", кто от него зависит. А в сеттере свойство уведомляет всех, что оно поменялось, а значит нужно пересчитать и то, что от него зависит.

    Еще один пример использования - ленивые вычисления. Например, мы можем создать middleware для express, который парсит куки и добавляет свойство cookies в объект запроса. Вот только куки нужны не каждый запрос, а их парсинг отнимает время. Через геттер можем сделать, чтоб парсинг происходил только при первом обращении к свойству cookies, тем самым улучшив производительность.
    Ответ написан
    Комментировать
  • Копирование массива с добавлением по смещениям, что?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Можно ли сделать ввод с клавиатуры в JS?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если речь о браузере, то можно ловить события клавиатуры (keypress, keydown или keyup) на странице или на отдельных ее элементах:
    https://developer.mozilla.org/ru/docs/Web/API/Keyb...

    Если речь о Node.JS, то есть поток доступный через process.stdin, а так же есть встроенный модуль readline, с помощью которого можно работать с вводом гораздо проще.
    Ответ написан
    Комментировать
  • Каким образом обрабатывать события с клавиатуры, мыши и тачскрина?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    С подходом "для каждого типа событий свой обработчик проще придерживаться SOLID, а общую логику можно вынести в отдельные функции
    Ответ написан
    Комментировать