Ответы пользователя по тегу JavaScript
  • Как подключить node js библиотеку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    План:
    1. создать пустой проект npm init Для этого понадобится сначала установить на комп node и npm
    2. установить в него этот шахматный модуль npm install ...
    3. создать файл main.js, где объединить ваш код и этот модуль
      import { Game } from 'js-chess-engine'; // 1-я строчка в файле main.js
      const game = new Game();
      // ... ваш код, взаимодействующий с game

    4. добавить в проект какой-нибудь сборщик, например, WebPack или RollupJS
    5. «собрать» этим сборщиком проект в один файл – который уже можно подключить в браузере
    Ответ написан
    Комментировать
  • Как выводить новые данные на страницу в зависимости от ответа пользователя?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    По данным из JSON ездит «курсор», указывающий на какой-то один вопрос.
    Переменная, в которой лежит ключ текущего вопроса. Сначала "1". Потом, в зависимости от ответа.
    Установили новое значение – показали новый вопрос.

    Можно заполнять массив «историей», чтобы добавить функционал шагать «назад» и потом вернуться «вперёд», или начать отвечать иначе.

    Ответ написан
    Комментировать
  • Написать функцию, принимающую массив сотрудников из объектов, и возвращающую массив строк. Какие ещё есть способы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Adamos верно заметил, что в задании просили функцию, а вы разово получаете результат. Согласен, что это вероятная причина отказа.

    Ещё вариант в копилку, принципиально не меняющий сути мэппинга:
    Array.from(employees, ({name, age}) => `Имя: ${name}, возраст: ${age}`)
    Ответ написан
    Комментировать
  • Как работает замыкание в js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Каждый вызов createCounter() создаёт и возвращает новую функцию. С которой в комплекте идёт свой новый «чемодан» замыкания, в котором лежит своя переменная counter.
    Каждый раз отдельная-новая.

    откуда берется counter при втором вызове console.log(z())

    Из того же «чемодана» от первого вызова createCounter()
    Ответ написан
    2 комментария
  • Как найти в одну переменную 2 класса?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    какой логической операцией хотите два класса сочетать?
    класс1 И класс2 — чтобы непременно оба были в наличии у элемента, и тогда только его брать;
    класс1 ИЛИ класс2 — достаточно любого одного из двух, ну или оба, вообще супер.

    Чтобы непременно оба класса одновременно присутствовали:
    document.querySelector('.popup__close.popup__area'); // без пробела


    Чтобы хотя бы один был:
    document.querySelector('.popup__close, .popup__area'); // через запятую


    Ну и помните, разумеется, что querySelector() выбирает первый подходящий найденный элемент. Один.
    А querySelectorAll() выберет все подходящие.
    Ответ написан
    Комментировать
  • Как вот это сделать на стандарте ES6?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Как-то так, наверное:
    import { initializeApp, credential } from 'firebase-admin';
    import serviceAccount from './my.json';
    
    initializeApp({
      credential: credential.cert(serviceAccount),
    });
    Ответ написан
    2 комментария
  • Как найти дату в тексте вида - 10 января 2023 г?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробуйте по-всякому. Например, 1-2 цифры, пробел, один из месяцов (перечислить), пробел, 4 цифры года.
    const months = 'января|февраля|марта';
    const re = new RegExp(`(\\d{1,2})\\s(${months})\\s(\\d{4})`);
    
    'блаблаблаб ла блаб ла 10 января 2023 блаблабла'.match(re)
    // [ "10 января 2023", "10", "января", "2023" ]
    Ответ написан
    Комментировать
  • Почему условие не возвращает true?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    - if (myArray.every((element, index) => index < myArray.length - 1 ? element <= element[index + 1] : true) {
    + if (myArray.every((element, index) => index < myArray.length - 1 ? element <= myArray[index + 1] : true)) {
    Ответ написан
    1 комментарий
  • Как на JS правильно конвертировать миллисекунды в формат 00:00:00,000?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    JS в браузере считает даты в часовом поясе браузера.
    timestamp в миллисекундах однозначно задаёт момент времени в зоне UTC.
    В это момент, например, в Москве на 3 часа больше. Поэтому браузер покажет
    Mon Mar 20 2023 07:42:33 GMT+0300 (Moscow Standard Time)


    Excel, видимо, предпочитает UTC, поэтому у него получилось 04:42

    Раз хочется получить именно в UTC, можно так:
    (new Date(1679287353711))
      .toISOString() // "2023-03-20T04:42:33.711Z"
      .substring(11, 23) // "04:42:33.711"
    ;
    Ответ написан
    Комментировать
  • Как с помощью регулярок на js заменить в тексте слова, которые могут ялвяться частью других слов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Регулярные выражения не инструмент, который умеет понимать корень слова. Как уже написали в комментариях, с числом букв споткнётесь о коллизию «думой» vs «думал» – первое надо капитализировать, второе нет.

    Так что предложил бы засучить рукава и перечислить все словоформы явно. Но и это не гарантирует безошибочность: подставят переносы слова, или омонимы.
    Омонимы сидели в баре, развалившись, как баре.


    В помощь
    учебник по регулярным выражениям.

    Граница слова: \b — работает только для ASCII, не годится для Unicode кириллицы.

    Unicode и флаг "u"

    Вариант выражения
    /дум.?(?=$|\s)/u – один опциональный символ, и смотреть вперёд, чтобы там был или конец строки или пробельный символ.

    const m = str => str.match(/дум.?(?=$|\s)/u);
    m('ду') // null
    m('дум') // ["дум"]
    m('дума') // ["дума"]
    m('думать') // null


    Вам нужно ещё разобраться и самостоятельно сделать такую же проверку до искомой строки: чтобы там было начало строки ^ или пробельный символ.
    Ответ написан
  • Как определить метод, а не свойство-функцию?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    MDN: Using super in method definitions:
    Only functions defined as methods have access to the super keyword. super.prop looks up the property on the prototype of the object that the method was initialized on.


    Learn.Javascript: Методы, а не свойства-функции
    Свойство [[HomeObject]] определено для методов как классов, так и обычных объектов. Но для объектов методы должны быть объявлены именно как method(), а не "method: function()".

    Для нас различий нет, но они есть для JavaScript.
    Ответ написан
  • Как превратить массив в число?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Небезопасный плохой вариант:
    const str = '1+1'; // строка
    const result = eval(str); // 2
    плохой кулхацкер передаст не "1+1", а злодейский код, который тупо выполнится и всё сломает.

    Вариант получше: разбивать строку "1+1" на токены: число, операция, число. Предположим, что задача из детского сада, поэтому числа всегда целые, неотрицательные, а операций всего 4: + - * / Разбить можно используя «регулярное выражение», или просто тупо искать в строке один из 4 операторов. С регуляркой примерно так:
    const str = '1+1'; // строка
    const parts = str.match(/(\d+)([-+*\/])(\d+)/); // массив [ "1+1", "1", "+", "1" ]
    if (!parts) throw 'не похоже на арифметику!';
    const [ _, A, op, B ] = parts;
    const a = +A; // из строки в число
    const b = +B;
    
    let result;
    if (op === '+') result = a + b;
    if (op === '-') result = a - b;
    if (op === '*') result = a * b;
    if (op === '/') result = a / b;
    
    console.log('result', result); // 2
    Ответ написан
    Комментировать
  • Как вывести два массива поочередно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Media.Mname.map(({ name }, i) => `${name} - ${Media.Link[i].link}`)
    // [ "vk - vkontakte", "tg - telegram", "inst - instagram ", "facebook - facebook" ]
    Ответ написан
    Комментировать
  • Исправьте, пожалуйста, код на JS. Почему он не работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно держать указатель на очередной элемент паттерна удаления.
    И знать ближайшую следующую позицию под удаление.

    В цикле идти по элементам исходного массива. Когда дошли до позиции под удаление, обновить указатель и следующую позицию, и никак не использовать значение. А иначе копировать текущий элемент в результат.
    const arr = Array.from({ length: 50 }, (_, i) => i); // [0, 1, 2, 3, ... 49]
    const pattern = [2, 5, 1, 2];
    const result = [];
    
    for (let i = 0, patternIndex = 0, toDeleteIndex = pattern[0] - 1; i < arr.length; i++) {
      if (i === toDeleteIndex) {
        patternIndex = (patternIndex + 1) % pattern.length; // 0, 1, 2, 3, 0, 1, 2, 3, ...
        toDeleteIndex += pattern[patternIndex];
      } else {
        result.push(arr[i]);
      }
    }
    
    console.log(result.join(', '));
    // 0, 2, 3, 4, 5, 8, 10, 12, 13, 14, 15, 18, 20, 22, 23, 24, 25, 28, 30, 32, 33, 34, 35, 38, 40, 42, 43, 44, 45, 48
    Такое задумывалось?
    Ответ написан
    Комментировать
  • Почему данный код выдает ошибку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Внутри скобок создаётся и тут же вызывается функция. (IIFE – immediately invoked functional expression)

    this для функции, объявленной как function определяется в момент её вызова. Если её вызывают будто она свойство объекта, этот объект будет this'ом.

    Внутри скобок function сама по себе, ни к кому не приделана, разве только к Глобальному. В данном случае window. Поэтому там this === window.

    Ну а window это не user. И там нет искомого свойства, скорее всего. Или есть, но неожиданно другое.
    Ответ написан
    Комментировать
  • Как выделить в массиве объектов максимальные и минимальные значения?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно сначала пройти по массиву и собрать минимальные/максимальные значения в объекты-словари типа
    maxValues = { fullPrice: 123, rating: 5 };
    minValues = { fullPrice: 103, rating: 3 };

    А затем второй раз пройтись по исходному массиву, расставляя пропсы min/max/value:
    Решение
    const src = [{ id: 1, fullPrice: 123, rating: 5 }, { id: 2, fullPrice: 103, rating: 3 }];
    
    const checkProps = ['fullPrice', 'rating'];
    
    const xValues = (method, initialValue) =>
      src.reduce((acc, c) => {
        Object.entries(c).forEach(([key, value]) => {
          if (checkProps.includes(key)) {
            acc[key] = Math[method](acc[key], value);
          }
        });
    
        return acc;
      }, Object.fromEntries(checkProps.map(propName => [propName, initialValue])));
    
    const minValues = xValues('min', Number.POSITIVE_INFINITY);
    const maxValues = xValues('max', Number.NEGATIVE_INFINITY);
    
    const result = src.map(item =>
      Object.fromEntries(
        Object.entries(item).map(([key, value]) => {
          if (checkProps.includes(key)) {
            return [key, { value, min: minValues[key] === value, max: maxValues[key] === value }];
          }
          return [key, value];
        })
      )
    );

    Результат:
    [
      {
        "id": 1,
        "fullPrice": {
          "value": 123,
          "min": false,
          "max": true
        },
        "rating": {
          "value": 5,
          "min": false,
          "max": true
        }
      },
      {
        "id": 2,
        "fullPrice": {
          "value": 103,
          "min": true,
          "max": false
        },
        "rating": {
          "value": 3,
          "min": true,
          "max": false
        }
      }
    ]

    Ответ написан
    Комментировать
  • Как дописывать + вместо %20?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Используйте URLSearchParams() — они кодируют пробел в плюс. В отличие от encodeURIComponent()

    (new URLSearchParams({q: 'QnA Habr'})).toString()
    // "q=QnA+Habr"
    Ответ написан
    Комментировать
  • Почему числу внутри setInterval нельзя прибавить другое число?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно так переписать, не меняя смысла:
    function foo(currentNumber){
        console.log(currentNumber);
        currentNumber++;
    }
    
    setInterval(foo, 1000, 5);
    Здесь, наверное, понятно, почему будет каждый раз 5 ?

    Ну, или даже так:
    foo(5); // выведет 5
    foo(5); // выведет 5
    foo(5); // выведет 5
    Внутренняя переменная функции изначально 5, выводит 5 и становится 10. Функция завершила работу, про переменную все забыли.
    Ответ написан
    Комментировать
  • Что надо сделать что бы таймер не сбрасывался при обновлении страницы?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    лучше один раз в начале определить дату-время окончания отсчёта, и её 1 раз сохранить сразу же в LocalStorage.

    По таймеру показывать разницу текущего времени и «времени Че».

    Таймеры не точны. Поэтому лучше зарядить этот таймер не на 1 секунду, а чаще, на 250 мс, например — это поможет избежать иногда проскакивания секунды или, наоборот, чуть более быстрой смены.
    Ответ написан
    Комментировать
  • Как добавить действия новым создаваемым карточкам?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Как исправить готовый код?
    Код надо привести в вопросе, окружив тегом <code>

    Сейчас у вас создаются 6 компонентов и тут же вешаются на них слушатели событий. См. все моменты с addEventListener('click', ...

    Когда создаётся вдруг новый ещё один компонент, на его суб-элементы слушателей клика уже никто не вешает, поэтому «действия» и не работают.

    Лучший вариант решения – слушать событие click выше, на общем родителе всех этих карточек – cardsContainer. Всего один слушатель. В обработчике разбирать, по кому, собственно, кликнули: смотреть класс кликнутого элемента и искать ближайшую к нему карточку.

    Так будут обработаны все карточки внутри этого общего родителя.

    spoiler
    cardsContainer.addEventListener('click', ({ target }) => {
      if (target.classList.contains('element__button')) {
        // toggle Like
        target.classList.toggle('element__button_active');   
      } else if (target.classList.contains('element__basket')) {
        // delete
        target.closest('.element').remove();
      } else if (target.classList.contains('element__item')) {
        // open picture
        openPicture({ target });
      }
    });
    // и убрать всё ставшее ненужным
    Ответ написан
    Комментировать