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

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Строки в JS неизменяемый тип данных, а значит все методы строк, которые подразумевают изменение строки могут лишь вернуть новую строку, но не изменить существующую.
    А следовательно данная строка ничего не делает:
    str.replace(/\s+/g, ' ').trim();

    Нужно возвращать не исходную строку, а результат данной операции:return str.replace(/\s+/g, ' ').trim();
    Ответ написан
    Комментировать
  • На чем лучше написать Desktop приложение?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если интересует только винда, то лучшим решением пожалуй будет C# и если нужна поддержка старых версий винды, то с WinForms.

    Насчет Electron.js - хорошее решение с низким порогом входа, работать будет не только на большинстве версий винды, но и под Linux и Mac. А насчет его производительности - эта байка идет не из-за того, что Electron медленный, а из-за кривых ручек большинства тех кто на нем пишет. Если писать нормально, с пониманием асинхронной природы JS, с вынесением бизнес логики в бэк часть и с асинхронным общением между бэк и UI частями - все будет работать достаточно быстро.
    В комментах к вопросу упомянули VSCode - хороший пример как готовить Electron правильно.

    Еще можно посмотреть в сторону tauri. UI пишется на веб технологиях (HTML, CSS, JS), бэк на Rust. Приложение будет гораздо легче, чем Electron и потенциально будет работать быстрее (хотя быстрее - это вообще мало от платформы зависит, кто и как пишет код тут гораздо важнее).
    Тут нужно учесть 2 момента:
    1. Если Вы никогда не работали с Rust, то в этот язык чуть тяжелее влиться чем в другие.
    2. Tauri использует нативный WebView для UI, а значит придется учитывать кроссбраузерность.

    Еще варианты:
    C++ + Qt
    Python + PyQt
    Java с ее окошками
    Ответ написан
    Комментировать
  • Как равномерно заполнить 3 массива с учетом высоты элементов?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ошибка в том что columnHeight нужно обновлять по тому же индексу, что и columns.
    Ну еще есть проблемы с тем, что исходные данные не упорядочены, а значит массивы будут заполняться не равномерно. Притом сортировать лучше по убыванию.
    Так же, если нужен оригинальный порядок, то его нужно сохранить, а потом так же восстанавливать сортировкой.

    // Сохраняем исходные индексы и сортируем по высоте по убыванию
    const preparedData = data
        .map((e, i) => ({i, e}))
        .sort((a, b) => b.e.height - a.e.height);
    
    for (const el of preparedData) {
        const { height } = el.e;
        // тут никогда не вернет -1, так как мы ищем элемент который точно есть в массиве - минимальный
        const index = columnHeight.indexOf(Math.min(...columnHeight));
        // обновляем данные массивов по выбранному индексу
        columnHeight[index] += height;
        columns[index].push(el);
    }
    
    // нормализуем columns
    for (let i = 0; i < columns.length; ++i) {
        // восстановим исходный порядок, отсортировав по сохраненному индексу по возрастанию
        columns[i].sort((a, b) => a.i - b.i);
        // избавимся от сохраненных индексов, оставив только исходные объекты
        columns[i] = columns[i].map(({ e }) => e);
    }
    Ответ написан
    Комментировать
  • Почему не работает onclick при работе с webpack?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    HTML ищет обработчики в только глобальной области видимости.
    Хранить что-либо в глобальной области видимости - чревато проблемами.
    webpack изолирует область видимости модулей в замыканиях дабы таких проблем не возникало.

    Навешивайте обработчики через JS, например как показал Yorido Satoshi
    Ответ написан
    Комментировать
  • Как сделать так что бы сайт спрашивал у пользователя доступ к камере?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    navigator.mediaDevices.getUserMedia({video: true})
    https://developer.mozilla.org/ru/docs/Web/API/Medi...

    Браузер сам запросит разрешение, когда Вы запросите камеру
    Ответ написан
    Комментировать
  • Как массив строк превратить в объект?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const arr = ['utmTerm=java', 'utmTerm=javascript', 'utmTerm=swift'];
    const res = arr.reduce((acc, item) => {
        const [key, value] = item.split('=', 2);
        (acc[key] ??= []).push(value);
        return acc;
    }, {});
    console.log(res);
    Ответ написан
    Комментировать
  • Как скопировать текст из iframe в переменную js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если в iframe загружена страница с того же origin (протокол + домен + порт) откуда загружена текущая - то Вы имеете полный доступ к его window через свойство contentWindow. Соответственно можете обращаться к его DOM, глобальным переменным, менять их и т.д.

    Если в iframe будет страница с другого origin, то ничего этого нет, с ней можно лишь общаться через postMessage api, но если страница не Ваша, то и скрипт для обработки postMessage + каких-либо еще действий Вы туда не вставите.

    Если сторонний сайт отдает нормальные CORS заголовки при запросе с Вашего сайта (что судя по вопросу не так, но все же), то можно скачать страницу как текст через fetch api и распарсить ее через DOMParser.

    В противном случае остается только делать прослойку у себя на сервере, тут простор фантазии может быть очень широким, от банального reverse proxy прямо в nginx до чего-то более умного на любом серверном ЯП.
    Ответ написан
    Комментировать
  • Как передать объект в класс js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Можно записать объект в свойство prototype временной функции и наследоваться от нее:
    function fromPrototype(proto) {
        function F() {}
        F.protoype = proto;
        return F;
    }
    
    const obj = {
        _sayHi() {
            console.log(`Hello, my name is ${this.name}!`);
        },
    };
    
    class Person extends fromPrototype(obj) {
        constructor(name, age) {
            this.name = name;
            this.age = age;
          
           if (this.age < 0 ) {
                this.age = 0;
            }
        }
    }
    Ответ написан
    2 комментария
  • Как сделать, чтобы событие вызывалось один раз?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Проблема вот тут:
    const remove = this.on(events

    Метод on у Вас ничего не возвращает, соответственно в remove будет undefined, функции там взяться неоткуда.
    Переменной events нет в скоупе данного метода, очевидно имелась в виду eventName

    А вообще, вместо массива колбэков для события лучше использовать Set, так метод off будет работать за O(1), а не за O(n) как сейчас.

    В методе once можно подписываться на событие через метод on, и отписываться через метод off при его наступлении (так например делает EventEmitter из node.js). Но стоит учесть момент, что off должен работать и для once событий, а у Вас будет записан колбэк созданный в once, а не тот, что передал пользователь. Вообще проще хранить 2 коллекции: для многоразовых для одноразовых событий, ну или параметризовать колбэки (тогда лучше хранить их в Map, где ключи - колбэки, а значения - их параметры).

    Ну и еще обратите внимание, что у Вас в методах emit и once колбэк пользователя вызывается по разному:
    callback.apply(this, args) и callback.call(null, args)
    Ответ написан
    1 комментарий
  • Какой нужен фреймворк для js, под мою задачу?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ответ написан
    Комментировать
  • Какая есть идиома для проверки [null]?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Мне нужно из: [null] получить просто []

    Если таких null много в вперемешку с полезными значениями, то можно отфильтровать:arr = arr.filter(el => el !== null);
    Ответ написан
    Комментировать
  • Что лучше использовать чтобы сделать задержку для отправки комментария?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    На клиенте просто делаем для кнопки:
    button.disable = true;
    setTimeout(() => {
      button.disable = false;
    }, 60_000);

    Основную же проверку нужно делать на сервере, просто не принимая запрос на добавление комментария пока не прошло время после предыдущего, т.к. клиентские проверки обходятся на раз.
    Ответ написан
    1 комментарий
  • Почему не происходит перезаписи значений параметров ф-ции?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Потому, что undefined в js - это специальное значение, суть которого быть значением по умолчанию для неинициализированных переменных.
    То есть инициализация переменной значением undefined - это все равно, что инициализация значением по умолчанию.
    Когда Вы в сигнатуре функции пишете b = 10 - это означает, что инициализируй b значением 10 если там инициализация по умолчанию (undefined).
    Ответ написан
    Комментировать
  • Все циклы, кроме for..in, могут работать только с итерируемыми объектами?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    С итерируемыми объектами работают только циклы for-of и for-await-of.

    В современном JS есть следующие виды циклов:

    1. while - цикл с условием
    // где condition - это некоторое выражение, которое можно скастовать к boolean
    while (condition) {
    }
    Данный цикл выполняется, пока условие condition истинно.

    2. do-while - цикл с постусловием
    do {
    } while (condition);
    Данный цикл выполняется как минимум 1 раз, условие condition проверяется после тела цикла и если оно истинно - запускается следующая итерация.

    3. for - цикл с инициализацией, условием и финальным выражением
    for (init; condition; final_expression) {
    }
    
    // основное применение - это цикл со счетчиком, но в целом мы не ограничены в применении
    for (let i = 0; i < 10; ++i) {
    }
    Перед циклом выполняется init, который может быть выражением или оператором объявления переменных (var, let, const). Перед каждой итерацией проверяется условие condition, пока это условие истинно - цикл будет выполняться. После каждой итерации выполняется final_expression.

    4. for-in - цикл по ключам объекта
    // где object - это некоторое выражение, которое можно скастовать к типу object
    for (const key in object) {
    }
    Данный цикл перебирает все перечислимые ключи самого объекта и всех объектов из его цепочки прототипов. Может работать медленно, а ключи из прототипа обычно не требуются, поэтому данный цикл не рекомендуется использовать.

    5. for-of - цикл по итерируемым объектам
    // где iterable - это некоторый объект с методом Symbol.iterator
    for (const value_variable of iterable) {
    }
    Перед итерацией создает итератор вызывая iterable[Symbol.iterator](), перед каждой итерацией дергает метод next у итератора, работает пока в возвращаемом из метода next объекте поле done не станет true, подставляет поле value в переменную value_variable. Цикл в примере выше можно реализовать в виде обычного for:
    {
      const iter = [1, 2, 3][Symbol.iterator]();
      for (let {done, value} = iter.next(); !done; ({done, value} = iter.next())) {
        const value_variable = value;
        {
          // тело исходного цикла
        }
      }
    }


    6. for-await-of - цикл по асинхронно итерируемым объектам
    // где iterable - это некоторый объект с методом Symbol.asyncIterator или методом Symbol.iterator
    for await (const value_variable of iterable) {
    }
    Перед итерацией создает итератор, одним из следующих способов:
    Если в объекте iterable есть метод Symbol.asyncIterator - то вызывает его.
    В противном случае вызывает метод Symbol.iterator.
    В остальном работает как for-of, с той разницей, что дополнительно применяет оператор await к значению итератора и в value_variable попадает то, что вернул данный await.
    Ответ написан
    Комментировать
  • Как преобразовать массив в строку js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    То что у Вас в примере - это вообще не валидный JS.
    Можно с объектами:
    const fields = {
         'Алтайский край': {
              'Барнаул': {}
              'Рубцовск': {}
         },
         'Новосибирская область': {
               'Новосибирск': {}
         },
    };
    console.log(JSON.stringify(fields));
    Ответ написан
  • Как вывести элементы из массива в список?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    У Вас только 1 ul на странице, а переменная i у Вас вообще никак не относится к найденным ul
    let ula = document.getElementsByTagName("ul")[0];
    
    for(let i = 0; i < arr.length; i++) {
      ula.insertAdjacentHTML('beforeend', `
      <li>
        <a href="#">${arr[i]}</a>
      </li> 
      `);
    }
    Ответ написан
    1 комментарий
  • Как можно сократить этот код?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const arr = [10, 20, 30, 50, 235, 3000];
    const digits = [1, 2, 5];
    for (const num of arr) {
      const digit = (num / 10 ** (Math.log10(num) | 0)) | 0;
      if (digits.includes(digit)) {
        console.log(num);
      }
    }
    Ответ написан
    Комментировать