Задать вопрос
Ответы пользователя по тегу JavaScript
  • Как распарсить 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, а общую логику можно вынести в отдельные функции
    Ответ написан
    Комментировать
  • ООП в JS отличается сильно от ООП компилируемых языков?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    3 принципа ООП - это миф, притом очень вредный.
    Инкапсуляция, наследование и полиморфизм относятся к ООП примерно как кухонный комбайн к варке блюд, их конечно можно использовать вместе, но и друг без друга они живут прекрасно.

    ООП - это про высокоуровневые абстракции представленные в виде объектов, а так же про взаимодействие этих объектов, путем вызова методов. Все. Никаких 3 принципов тут нет. И это примерно одинаково, что в JS, что в C#, что в Java, что в C++, а разница в реализации тут не существенна, Вы о ней знаете, только потому что абстракции текут.

    Инкапсуляция - это сокрытие сложности. Опять же все. Забудьте весь бред про приватные поля и тому подобное. Это не более чем частный случай. И замыкания - это тоже частный случай инкапсуляции. А еще, когда из модуля Вы экспортируете не все подряд (привет ReasonML), а только высокоуровневые штуки, оставляя все остальное недоступным извне. А еще когда некоторое API (REST/GraphQL/RPC/etc.) отгораживает Вас от прямого общения с базой данных - это тоже инкапсуляция.

    Полиморфизм - это возможность некоторой сущности работать с разными типами данных и возможно адаптироваться под них. А еще полиморфизм разный бывает. Помимо полиморфизма подтипов, который чаще всего и приписывают к ООП, бывают и другие. Например очень распространен параметрический полиморфизм, в большинстве языков представленный дженериками. А еще бывает ad-hoc полиморфизм (перегрузки).
    Но даже если рассматривать только полиморфизм подтипов (это когда между типами есть иерархия, то есть отношения подтип-надтип, и мы в переменную/аргумент/поле надтипа можем присвоить значение подтипа), то и тут нет не слова про ООП. Яркий пример - TypeScript, где есть тип unknown, являющийся надтипом любого другого типа и в который можно присвоить значение любого типа, а так же есть тип never, являющийся подтипом любого другого типа и который можно присвоить в любой другой тип.
    Ну и касательно JS, в нем вообще все полиморфно, ибо динамическая типизация.

    Наследование - это вообще частный случай полиморфизма подтипов, отдельно выделяют пожалуй лишь потому, что он не только про типы (как полиморфизм), а еще и про реализации, которые наследуются. И опять же, ничего тут про ООП нет. Наследование вполне может жить и без ООП,
    например во вполне себе структурно-процедурном Си
    #include <stdio.h>
    
    struct Parent
    {
        int a;
        int b;
    };
    
    struct Child
    {
        struct Parent __super;
        int c;
    };
    
    void f(struct Parent* v)
    {
        printf("a: %d\nb: %d\n", v->a, v->b);
    }
    
    int main()
    {
        struct Child v = {{10, 20}, 30};
        f((struct Parent*)&v);
        printf("c: %d\n", v.c);
        return 0;
    }


    P.S. JS вполне себе компилируемый язык, у v8 даже ассемблерный код попросить можно, который он накомпилит с Вашего JS.
    Ответ написан
    1 комментарий
  • Как вызвать функцию из прототипа (рекурсия)?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://developer.mozilla.org/ru/docs/Web/JavaScri...
    https://developer.mozilla.org/ru/docs/Web/JavaScri...

    А вообще, мутировать прототип не своих сущностей, а особенно глобальных - очень плохо, в лучшем случае Вас побьют, в худшем...
    И главное зачем? Есть https://developer.mozilla.org/ru/docs/Web/JavaScri...

    Ну и еще, у рекурсии есть ограничение на размер call stack, если это тестовое, то я бы обязательно вставил в проверку такой массивчик:
    let arr = [1];
    for (let i = 0; i < 65536; i++) arr = [arr];
    Ответ написан
    Комментировать
  • Не могу понять как это сделать?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    В браузере нет require
    Этот код или под нодой должен запускаться или собираться с помощью webpack
    Ответ написан
    Комментировать