Ответы пользователя по тегу JavaScript
  • Есть кастомный вариант 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
    Ответ написан
    Комментировать
  • Как посчитать количество функций в коде JS?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Такие задачи однозначно решаются обходом AST. Возьмите общеизвестный парсер и инструмент для обхода его дерева, например связка из @babel/parser и @babel/traverse подойдет.
    Так же можно посмотреть в какие ноды что парсится с помощью https://astexplorer.net/ - в нем несколько языков, а для js/ts на выбор есть несколько парсеров.
    Вам по сути нужно найти FunctionDeclaration содержащий в body ReturnStatement и извлечь из него Identifier соответствующий имени. А для второй части - FunctionDeclaration с ArgumentsList не нулевой длины.
    Ну и так как в условии сказано, что внутрь не заходить, то можно пройтись лишь по верхнему уровню, тогда @babel/traverse и не нужен даже
    Ответ написан
    3 комментария
  • Как написать регулярку на допуск только цифр и точек?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Выбирайте, что больше нравится:
    /^(\d|\.)*$/
    /^[.0-9]*$/
    /^[\d.]*$/


    Но я бы все же ограничил одной точкой:/^\d*\.?\d*$/
    Ответ написан
    3 комментария
  • Можно ли несколько раз проксировать объект?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если свойства заранее известны, то проще get/set сделать.
    А Proxy перехватывает все поля без исключения. Можно разве не все хандлеры определять, вместо пропущенных будут использоваться одноименный функции из Reflect, что по сути приведет к поведению как у оригинального объекта.
    Ну и да, на один объект можно повесить любое число Proxy и о них не узнает ни оригинальный объект ни другие прокси.
    Ответ написан
    Комментировать
  • Как происходит всплытие переменной?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Объявления переменных и функций всплывают на верх области видимости, у var и function (та что declaration) - это внешняя функция или модуль (если на верхнем уровне дело происходит), у let и const - блок, то есть после всплытия, внутри движка Ваш код будет выглядеть так:
    var foo; 
    function bar() {
        var foo; // эта foo перекрывает foo из внешней области видимости, и поэтому в функции используется она
        if (!foo) { 
            foo = 10; 
        } 
        console.log(foo); 
    }
    foo = 1;
    bar(); //--> 10


    Так же важно знать, что хотя let и const всплывают наверх блока, но использовать их до фактического места объявления нельзя, так будет ошибка:
    {
        console.log(x); // ReferenceError: Cannot access 'x' before initialization
        let x;
    }
    Это механизм защиты "от дурака" и называется он "мертвое всплытие". По этому всегда лучше использовать let или const, притом const предпочтительнее если переменная не меняется, так как дает больше гарантий.
    Ответ написан
    2 комментария
  • В чем превосходство Typescript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Как бы это странно не звучало, но одно из главных преимуществ TypeScript - это ускорение разработки в несколько раз. Да, когда еще ничего нет - разработка незначительно замедлится, так как помимо логики нужно описать еще и типы. Но это только в начале. И это не только возможность писать большую часть кода с помощью автодополнения. Поддержка существующего кода занимает в десятки раз больше времени, чем его начальное написание. Стоит ли вложить несколько лишних часов на старте, чтоб сэкономить в последствии месяцы? Как по мне стоит.

    Еще одним огромным плюсом является возможность проектировать на типах. Познав дзен TypeScript'а я перестал пользоваться UML, так как типы дают мне ту же наглядность, но при этом еще и сокращают время, так как типы - это уже код. Ну и источник правды остается один. Бизнес требования выраженные в типах не дают отклонится от них при написании логики, исключая возможность неправильной трактовки задачи. Перенеся задачу в типы, я могу обсудить ее с коллегами и исправить неточности еще до написания кода, что опять же сильно экономит время.

    Ну и отвчечу на некоторые Ваши сомнения:
    TSLint в VSCode прям жутко тугой
    TSLint официально deprecated, вместо него стоит использовать плагин к eslint, заодно можете мой конфиг попробовать.

    Типы? Есть JSDOC
    JSDoc в плане типов не умеет и 10% того, что умеет TypeScript. Кроме того, никто в здравом уме не пишет JSDoc на приватную логику, а значит проверки типов там не будет. JSDoc не гарантирует корректность рефакторинга, а вот благодаря TypeScript я, опять таки, точно не забуду обновить JSDoc.

    многие библиотеки nodejs не имеют типов
    может лет 5 назад так и было, но сейчас встретить библиотеку без типов - скорее исключение. Если библиотека популярная, но не предоставляет типов, скорее всего их уже написал кто-то другой, достаточно просто установить одноименный модуль из npm скоупа types и все будет работать само.

    Поддержка браузерами скомпилированного кода? Да какбы почти весь JS имеет поддержку 95%+, тот же Babel уже забыл когда использовал.
    Вообще это не основная задача компилятора TypeScript, а опциональная возможность. И babel + preset-env с ней справляются гораздо лучше. И никто не мешает использовать их вместе. А еще думаю вопрос времени, когда кто-то напишет оптимизатор кода использующий информацию о типах из TS.

    Примерно в каждой второй есть инстансы, на которые смотришь - и чешешь репу - а как называется тип этой переменной в @types/?
    import {someObject} from 'some-library';
    
    type TypeFromValue = typeof someObject;
    const valueCopy: TypeFromValue = {
        ...someObject,
        type: 'overrides',
        with: 'type check',
    };
    и кстати, вот пример того что JSDoc типы не умеют.

    //@ts-check
    и почти везде останется бесполезный any.

    P.S. удачи такие типы на JSDoc описывать
    P.P.S. Еще прелести современного TypeScript невозможные у...
    Ответ написан
    8 комментариев
  • Почему нет разницы в производительности между fork mode и cluster mode в PM2?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Во-первых, cluster мод отличается от fork только тем, что умеет шарить слушаемые tcp порты между процессами. И там и там процессов будет ровно столько, сколько настроите, а значение по умолчанию - количество физических потоков (логических ядер) системы.
    Во-вторых, "двухядерный сервак с 2Гб оперативой" выглядит как виртуалка на большом сервере, где Вам выделили некоторые ресурсы. И ваши 2 ядра вполне могут быть логическими, но физически - 1 ядром или даже его половиной (если 4 потока на ядро), за счет гипертрединга. Вот только гипертрединг штука нацеленная на лучшую утилизацию ресурсов процессора при простоях, а вот при большой нагрузке он вполне себе может замедлить систему, особенно основанную на кооперативной многозадачности (асинхронном исполнении) как в ноде.
    Ответ написан
    1 комментарий
  • Как сделать чтобы отрабатывало событие зажатой ЛКМ и движения мыши?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Вы функцию playAudio отдаете как event listener, в нее придет единственный аргумент - объект события, откуда должен взяться data - вообще не понятно.

    Ну и вот так работать не будет:
    piano.addEventListener("mousedown", startKeyActive, playAudio);
    Ответ написан
  • Как менять динамически имя переменной?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    locations[`coord_${count}`]
    это же базовый синтаксис языка...
    Ответ написан
    Комментировать
  • Как седлать рандом с примером ниже толь с шансом на выпадение какого либо варианта (JavaScript Jquery)?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    console.log(getRandomVariant([
        {chance: 0.4, value: 'Текст1'},
        {chance: 0.2, value: 'Текст2'},
        {chance: 0.15, value: 'Текст3'},
        {chance: 0.25, value: 'Текст4'},
    ]));
    
    function getRandomVariant(variants) {
        const sortedVariants = getRandomVariant.cache.get(variants) ?? getRandomVariant.cache
              .set(variants, variants.slice().sort((a, b) => b.chance - a.chance))
              .get(variants);
        let rand = Math.random();
        for (const {chance, value} of sortedVariants) {
            if (chance > rand) return value;
            rand -= chance;
        }
    }
    getRandomVariant.cache = new WeakMap();
    Ответ написан
    Комментировать
  • Как посчитать среднее значение данных в массиве?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const averages = Array.from(
        arr
            .flatMap(v => v.properties.groups)
            .reduce((acc, {id, 'well-being': value}) => {
                const [count, total] = acc.get(id) ?? [0, 0];
                acc.set(id, [count + 1, total + value]);
                return acc;
            }, new Map())
            .entries(),
        ([id, [count, total]]) => ({id, average: total / count}),
    );
    console.log(averages);
    Ответ написан
    Комментировать