Задать вопрос
  • Как в консоле в Node.js вывести методы которые есть у экземпляра класса?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Во-первых, логировать через console.dir с опцией showHidden: true
    // Для класса ClassName
    console.dir(ClassName.prototype, {showHidden: true});
    
    // Для любого объекта или инстанса класса obj
    console.dir(Object.getPrototypeOf(obj), {showHidden: true});


    Ну и зная, что любой прототип - это тоже объект, а корневой прототип всегда null, то можно просто пройтись рекурсивно, чтоб посмотреть всю цепочку:
    class SomeClass extends Array {}
    function collectPrototypesChain(obj) {
      const proto = Object.getPrototypeOf(obj);
      if(!proto) { return null; }
      const {name} = proto.constructor;
      return {name, proto, next: collectPrototypesChain(proto)};
    }
    
    console.dir(collectPrototypesChain(new SomeClass()), {showHidden: true, depth: 4});
    Ответ написан
    3 комментария
  • На чём написаны интерпретаторы и компиляторы разных языков?

    bingo347
    @bingo347
    Crazy on performance...
    Как уже сказали в других ответах, компиляторы и интерпретаторы пишут так же на языках программирования.
    Насчет компиляторов так же считается, что зрелый язык позволяет написать собственный компилятор на себе самом. И для многих компилируемых языков компиляторы действительно написаны на них самих. Но тем не менее, самый первый компилятор все равно придется написать на другом языке, в современном мире для этого очень часто выбирают OCaml, хотя и другие языки вполне подойдут.
    Интерпретируемые языки нуждаются в интерпретаторе, который пишется на компилируемых языках. Простор выбора тут огромен, но чаще все же встречается или C или C++.
    Так же еще встречается JIT компиляция (js (не всегда), lua), при которой весь процесс компиляции происходит непосредственно перед выполнением, а так же гибридная AOT+JIT компиляция (C#, Java), когда исходный код компилируется в байткод при разработке (AOT), а перед исполнением байткод компилируется в машинный код (JIT), что позволяет получить плюсы от обоих типов компиляции. JIT компиляторы как и интерпретаторы как правило пишут на AOT-компилируемых языках.
    Ну и надо не забывать, что почти у каждого языка бывает стандартная библиотека, которая может быть написана как на самом языке (C, C++, Go, Rust), на самом языке + на другом, чаще на C или C++ (js (не во всех движках), C#, Java, python (не уверен, что он не к следующему типу больше)), либо полностью на другом языке (php, python (?)). Тут все сильно зависит, на сколько в языке доступно низкоуровневое общение с ОС и железом, а так же на сколько это быстро можно выполнить не ломая "сахара" языка.
    Ответ написан
    Комментировать
  • Как сгенерировать нечётное рандомное число?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если диапазон не будет выходить за пределы int32, то проще всего принудительно устанавливать нулевой бит в 1:
    function randomEvenInt(min, max) {
      return (min + Math.random() * (max - min)) | 1;
    }

    Иначе можно проверять на четность и добавлять или отнимать единицу в случае четного результата:
    function randomEvenInt(min, max) {
      const result = Math.floor(min + Math.random() * (max - min));
      return result + ((result % 2) - 1);
    }
    Ответ написан
  • Продолжится ли выполняться процесс после прерывания соединения SSH?

    bingo347
    @bingo347
    Crazy on performance...
    Tmux Вам в помощь
    Ответ написан
    Комментировать
  • Как протестировать атрибут компонента, если это функция?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Не совсем понятно, что конкретно Вы хотите протестировать, но скорее всего Вам нужно это:
    https://jestjs.io/docs/ru/mock-functions
    Ответ написан
    Комментировать
  • Что не так с конфигом webpack?

    bingo347
    @bingo347
    Crazy on performance...
    Чтоб webpack понимал html как модуль нужен html-loader натравленный на файлы с расширением .html
    В entry указывается именно корневые модули (те которые подключают все остальные, с которых начинается программа)
    Вам нужно указать в entry главный js файл, скорее всего вот этот https://github.com/danger-enemy/webpack/blob/maste...
    А html для Вас создаст HTMLWebpackPlugin

    Так же обратите внимание, что в этом .js файле Вы используете jsx синтаксис, а preset-react у Вас подключен только для файлов .jsx
    Ответ написан
    Комментировать
  • Как слушать несколько портов и адресов в http.js?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Придется поднять 2 инстанса http сервера, каждый на своем порту и адресе.
    В принципе их можно будет использовать с общим app, так как и у req и у res есть свойство socket, являющееся инстансом net.Socket, а значит из него можно получить адрес и порт:
    https://nodejs.org/dist/latest-v14.x/docs/api/http...
    https://nodejs.org/dist/latest-v14.x/docs/api/http...
    https://nodejs.org/dist/latest-v14.x/docs/api/net....
    var app = require('express')();
    var http = require('http');
    var server1 = http.createServer(app);
    var server2 = http.createServer(app);
    
    server1.listen(PORT1, ADDRESS1);
    server2.listen(PORT2, ADDRESS2);

    io правда придется создать 2 инстанса, но обработчики событий опять же можно навесить общие.
    Ответ написан
    Комментировать
  • Когда надо пушить git push --tags?

    bingo347
    @bingo347
    Crazy on performance...
    git push просто без параметров зальет все локальные коммиты в последнюю удаленную ветку, если git знает о том, какая последняя конечно
    git push с флагом -u позволяет указать, какой именно удаленный репозиторий (в вопросе это origin) и в какую в нем ветку (в вопросе это master) заливать коммиты
    git remote управляет удаленными репозиториями
    в частности git remote add добавляет новый под указанным именем (в вопросе это origin) и находящийся под указанным url (в вопросе это https://github.com/.git)
    git push --tagsзаливает в последнюю удаленную ветку только тэги, без коммитов
    но тэг - это всего лишь символьная ссылка на конкретный коммит и без самого коммита смысла в ней нет
    поэтому git push --tags должно идти после git push
    Ответ написан
    2 комментария
  • Узнать данные из библиотеки .so?

    bingo347
    @bingo347
    Crazy on performance...
    Ответ написан
    Комментировать
  • Как изолировать или обнулить встраиваемое приложение от внешних стилей?

    bingo347
    @bingo347
    Crazy on performance...
    Встраиваемое приложение должно быть в iframe, только так на сегодня можно 100% изолировать и стили и скрипты.
    Элементарно будет на сайте банальное
    div {
      color: red !important;
    }
    и Ваше приложение уже будет выглядеть не так.
    Ну а еще встречается js с манкипатчингом.
    А iframe вполне хорошо Вас защитит и от того и от другого
    Ответ написан
    2 комментария
  • Как выбросить ошибку из промиса?

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

    Для начала я отрефакторю вот этот кусок:
    const minSalary = Math.min(...employeeData.map(({ salary }) => salary));
    minSalaryEmployee = employeeData.filter(({ salary }) => {
        return salary === minSalary;
    });
    const [id, oldSalary] = [
        minSalaryEmployee[0].id,
        minSalaryEmployee[0].salary,
    ];
    const newSalary = oldSalary + (oldSalary / 100) * 20;
    return { id: id, salary: newSalary };
    ибо тут твориться полная жесть...
    Если привести в более читабельный вид:
    const minSalary = Math.min(...employeeData.map(({salary}) => salary));
    const minSalaryEmployee = employeeData.find(({salary}) => salary === minSalary);
    const {id, salary: oldSalary} = minSalaryEmployee;
    const newSalary = oldSalary + (oldSalary / 100) * 20;
    return {id, salary: newSalary};
    то сразу можно увидеть простор для оптимизации поиска минимума:
    const [minSalaryEmployee] = employeeData.reduce(([minEmployee, minSalary], employee) => {
        const {salary} = employee;
        return (salary < minSalary
            ? [employee, salary]
            : [minEmployee, minSalary]
        );
    }, [null, Infinity]);
    А заодно и формулу
    const newSalary = oldSalary + (oldSalary / 100) * 20;
    применив алгебру за 5 класс можно упростить доconst newSalary = oldSalary * 1.2;

    Следующим шагом стоит развернуть все промисы. Вообще вкладывать промисы в друг друга не очень хорошая идея. Наличие .then внутри колбэка другого .then или колбэка-раннера new Promise - воняет очень скверно.

    Немного поколдовав, заодно исправив ошибки с колбэками .then без return, получаем более читабельный, а главное работающий код:
    function increaseSalary() {
        return api.getEmployees()
            .then(employeeData => {
                const [minSalaryEmployee] = employeeData.reduce(([minEmployee, minSalary], employee) => {
                    const {salary} = employee;
                    return (salary < minSalary
                        ? [employee, salary]
                        : [minEmployee, minSalary]
                    );
                }, [null, Infinity]);
                const {id, salary: oldSalary} = minSalaryEmployee;
                const newSalary = oldSalary * 1.2;
                return {id, salary: newSalary};
            })
            .then(({id, salary}) => api.setEmployeeSalary(id, salary))
            .then(({name, id, salary}) => api.notifyEmployee(id, `Hello, ${name}! Congratulations, your new salary is ${salary}!`))
            .catch(e => api.notifyAdmin(e));
    }


    P.S. я бы еще бил все это добро на отдельные функции, ибо complexity 10 это все еще много...

    import api from 'path/to/api';
    
    export function increaseSalary() {
        return api.getEmployees()
            .then(findEmployeeWithMinSalary)
            .then(calculateNewSalary)
            .then(setEmployeeSalary)
            .then(notifyEmployee)
            .catch(notifyAdmin);
    }
    
    function findEmployeeWithMinSalary(employeeData) {
        const [minSalaryEmployee] = employeeData.reduce(minSalaryEmployeeReducer, [null, Infinity]);
        return minSalaryEmployee;
    }
    
    // Complexity is 3 - это самая сложная функция
    function minSalaryEmployeeReducer([minEmployee, minSalary], employee) {
        const {salary} = employee;
        return (salary < minSalary
            ? [employee, salary]
            : [minEmployee, minSalary]
        );
    }
    
    function calculateNewSalary({id, salary}) {
        return {
            id,
            salary: salary * 1.2
        };
    }
    
    function setEmployeeSalary({id, salary}) {
        return api.setEmployeeSalary(id, salary);
    }
    
    function notifyEmployee({name, id, salary}) {
        return api.notifyEmployee(id, `Hello, ${name}! Congratulations, your new salary is ${salary}!`);
    }
    
    function notifyAdmin(e) {
        return api.notifyAdmin(e);
    }
    Ответ написан
    1 комментарий
  • Добавлять/убирать класс у элементов при скролле?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Вопрос поднимался здесь уже много раз...

    1. Оптимизировать можно с помощью IntersectionObserver
    2. Просто убирайте класс со всех остальных элементов
    Ответ написан
    Комментировать
  • Как обернуть данные из колбэков в массив?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Решение 0xD34F имеет сложность O(n2) из-за использования метода every
    Если это тестовое задание, могут и придраться, так как обычный счетчик позволяет решить со сложностью O(n)
    function getUsersInfo(ids, callback) {
      const {length} = ids;
      const results = Array(length);
      let doneCount = 0;
      ids.forEach((id, i) => {
        getUserInfo(id, user => {
          results[i] = user;
          doneCount++;
          if(doneCount === length) {
            callback(result);
          }
        });
      });
    }

    Ну и замечу, что Promise.all в v8 под капотом использует именно такой подход (разве что подсчет ведут от length к 0):
    https://github.com/v8/v8/blob/master/src/builtins/...
    Ответ написан
    1 комментарий
  • Как сделать option якорной ссылкой?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ответ написан
    Комментировать
  • Каким путем лучше пойти при хранении индентефекатора сессии?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Самый безопасный способ - кука с флагами secure и http-only, с ней может работать только сервер и передается она только по https.
    Все остальное спокойно уводится любым сторонним скриптом на Вашем сайте
    Ответ написан
    Комментировать
  • Одно ли и то же эти куски кода?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    1 - function expression
    Функция будет анонимная (без имени), что затруднит отладку, а так же не позволит делать рекурсивные вызовы.
    var всплывет наверх функции в которой была объявлена (оборачивающей), но до присваивания будет иметь значение undefined, вызов приведет к ошибке.
    Данный тип функций вообще не должен использоваться в нормальном коде.
    Функцию можно переопределить в последствии

    2 - named function expression
    Похоже на предыдущее, но имеет имя, что упрощает отладку и позволяет делать рекурсивные вызовы. В остальном все тоже самое.
    Вот так в переменную опять же присваивать не стоит, для дебага хватит стрелочной функции присвоенной в константу (в дебаггере примет имя константы). Но рационально использовать для колбэков, где нужна рекурсия или опять же для удобного дебага.

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

    Добавлю еще 4 - arrow function expressionconst func = () => {};на сегодня лучше использовать его вместо function expression
    Ответ написан
    3 комментария
  • Как при рекурсивном переборе древовидных объектов вызывать fetch на каждый item и на выходе получать измененный массив?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const addingOptions = arr => Promise.all(arr.map(
        item => Promise.all([
            fetchOptions(item.id),
            item.children.length ? addingOptions(item.children) : []
        ]).then(([options, children]) => ({
            ...item,
            options,
            children
        }))
    ));
    Ответ написан
    Комментировать
  • Как предлагать пользователям рандомный вопрос?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Аналог electron только на GO?

    bingo347
    @bingo347
    Crazy on performance...
    Electron построен поверх CEF внедренного в ноду как нативный аддон.
    В рендер процессе нода подключается через libnode
    Все это вполне общается через сишный abi с которым умеет работать cgo.
    Ответ написан
    Комментировать
  • Как реализовать такое?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Для начала наш бэк должен уметь отвечать на запрос вида "дай мне N товаров после товара X", иначе такая кнопка в принципе не имеет смысл.
    Так вот, при нажатии на кнопку "Показать больше" мы первым делом должны ее заблокировать (чтоб пользователь не на тыкал лишнего) и показать лоадер (вдруг инет пользователя медленный), а затем отправить наш запрос к бэку, чтоб он дал нам данные о дополнительных товарах.
    Когда данные загрузились, отрисовываем их в конец и в зависимости от того, есть ли у бэка еще товары (это он тоже должен нам сказать) мы или разблокируем или прячем кнопку "Показать больше".
    Все.
    Ответ написан
    Комментировать