• Как прочитать файл .json?

    bingo347
    @bingo347
    Crazy on performance...
    console.log(
      require(path.join(PATHS.src, 'manifest.json'))
    );
    Ответ написан
    1 комментарий
  • Можно ли сделать ввод с клавиатуры в 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 и о них не узнает ни оригинальный объект ни другие прокси.
    Ответ написан
    Комментировать
  • Как в VS Code проверить проект на типизацию TypeScript?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    лишь ошибки типизации которые не мешают компиляции
    Если проект компилируется - то все типы сошлись. Если проект компилируется, а ошибка все таки есть - значит типы криво описаны.
    Как проверять все файлы проекта на правильность типизации?
    Скомпилировать проект.

    Но, если допустим, изменить какой-нибудь тип (интерфейс), а файл, который на него ссылается и использует будет закрыт, то ошибку никакую не выдаст.
    И это хорошо. Если TypeScript LSP будет перепроверять весь проект на каждый чих, а не только открытые файлы, то писать что-то сложнее todo листа будет невозможно...

    Знаю, существуют ESLint, TSLint.
    Они тоже для статического анализа, но для немного другого. В VSCode они так же чекают только открытые файлы, из тех же соображений производительности.
    TSLint устарел. ESLint ставьте отсюда: https://marketplace.visualstudio.com/items?itemNam...
    Ответ написан
    Комментировать
  • Как происходит всплытие переменной?

    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}`]
    это же базовый синтаксис языка...
    Ответ написан
    Комментировать
  • Стоит ли использовать везде GraphQL?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Если Вы не пишите внешнее или публичное API, то GraphQL и REST - будут крайне отвратительным выбором. Они ограничивают Вас в низкоуровневом CRUD, создавая больше проблем, чем решают, а главное затрудняют выражать Ваше API в терминах доменной области.
    Посмотрите в сторону RPC протоколов, и посмотрите как элегантно на них можно описать конкретно Ваш домен. Да и выбор тут огромен: Apache Thrift, gRPC, JSON-RPC, а так же мой любимый, но почему-то малоизвестный в русскоязычном интернете E/A/?T (расшифровывается как entity/action/optional-target)
    Ответ написан
    4 комментария