Задать вопрос
Ответы пользователя по тегу JavaScript
  • Содержимое массива меняется само по себе?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    defaultDepts заполнен объектами. Объекты передаются по ссылке в JS.
    [...defaultDepts] создаёт новый массив старых объектов. Меняете что-то внутри этих объектов — меняется и внутри defaultDepts.

    Нужна «глубокая копия».

    Причём не просто
    [...this.defaultDepartments].map(item => {...item})
    , а нормальная рекурсивная. Ведь ещё и свойство colleagues, с свою очередь, содержит массив объектов.
    Ответ написан
    3 комментария
  • Почему 0.35 -> toFixed(1) = 0.3?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    какая несправедливость:
    [.05, .15, .25, .35, .45, .55, .65, .75, .85, .95]
    .map(v => `${v} - ${v.toFixed(1)}`).join("\n");
    /*
    0.05 - 0.1
    0.15 - 0.1
    0.25 - 0.3
    0.35 - 0.3
    0.45 - 0.5
    0.55 - 0.6
    0.65 - 0.7
    0.75 - 0.8
    0.85 - 0.8
    0.95 - 0.9
    */
    1-1, 3-3, 8-8
    Ответ написан
    Комментировать
  • Как на чистом JavaScript получить значение атрибута элемента по классу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    document.addEventListener('click', event => {
      const { target } = event;
      if (target.tagName !== 'DIV'
          || !target.classList.contains('elem')) {
        return;
      }
      console.log(target.dataset.name);
    });


    Песочница
    Ответ написан
    7 комментариев
  • Почему split не разбивает строку на строку + число?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    с регулярками можно проще.
    Разбить на группы только-буквы или только-цифры:
    let re = /((\D+)|(\d+))/g; // \D не-цифра, \d цифра
    
    'user100'.match(re)  // [ "user", "100" ]
    '2022habr06QnA'.match(re)  // [ "2022", "habr", "06", "QnA" ]
    Ответ написан
    1 комментарий
  • Почему не работает код для перестановки блоков?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробуйте как-то так:
    const blockRelocate = () => {
      const elSource = document.querySelector('.description-wrapper');
      if (!elSource) {
        return setTimeout(blockRelocate, 150);
      }
      const elTarget = document.querySelector('.item-calculator_container');
      elTarget.insertAdjacentElement('beforebegin', elSource);
    }
    
    blockRelocate();
    Ответ написан
  • Как решить проблемисы с Cannot read properties of null?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно слушать клики не на самих div'ах под удаление, а выше. Только создаваемые div'ы как-то помечать, например, доп. классом, чтобы не поудалять лишнее.
    В слушателе кликов выше проверять: есть ли у кликнутого элемента event.target тот самый класс.
    Ответ написан
    1 комментарий
  • Где используется Map и Set в JavaScript (примеры использования)?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Set удобен, например, когда нужно оставить из набора данных только уникальные.
    пример кода
    const data = [ 1, 2, 2, 3, 3, 3 ];
    const unique = [...new Set(data)];
    unique // [ 1, 2, 3 ]

    Map хорош тем, что ключами в нём могут быть и объекты. Например, HTML-элементы, для которых захочется хранить какие-то данные. И Map запоминает порядок добавления элементов, что может быть полезно при переборе.
    Ответ написан
    Комментировать
  • Как сделать кликабельными кнопки и чтобы им переходили стили?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    CSS классами опишите вид обычной кнопки и «активной» – с доп. классом .active

    По клику на кнопку снимайте класс .active у всех кнопок,
    и затем добавляйте его только кликнутой кнопке.
    Ответ написан
    Комментировать
  • Почему когда я обнуляю value в коллекции WeakMap, value остается прежним?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    если убрать весь пафос WeakMap, с простыми переменными всё точно так же:
    let value = { name: 'iOne' };
    let x = value; // ещё одна "ссылка" на объект
    
    value = null; // или  delete value; – то же самое
    x //  { name: "iOne" }
    Разберитесь с основами: Объекты и ссылки на объекты. Т.к. в объекте weakMap есть ссылка от ключа на объект-значение — объект вполне себе сохраняется. Главное, что всё ещё жива ссылка на объект-ключ key.

    Особенность WeakMap  – в тех объектах, которые выступают не значениями, а ключами.
    const weakMap = new WeakMap();
    let value = {name: 'Ivan'};
    let key = {};
    
    // добавление нового элемента
    weakMap.set(key, value);
    
    // обнуление
    delete key;
    Теперь, хоть объект, на который указывала переменная key всё ещё используется в качестве ключа в WeakMap, сборщик мусора, при срабатывании, таки удалит его.
    Ответ написан
    Комментировать
  • Как правильно работать с Promise?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вопрос если разница в таких записях?

    Только в передаваемом значении:
    • resolve(script) передаст дальше по цепочке этот script (который никому не нужен, похоже).
    • script.onload = resolve передаст по цепочке объект события (тоже всем по барабану)

    почему такой ее вызов дает ошибку script.onload = resolve(script);
    потому, что нужна функция, которую вызовут позже, а не мгновенный результат её выполнения.
    Ответ написан
    Комментировать
  • Почему filter возвращает пустой массив?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надо же фильтровать по индексам элементов массива, а у вас по самим элементам, которые совсем не числа и не делятся на 2 )
    // odd.filter(item => item%2);
    odd.filter((_, i) => i & 1);
    Ответ написан
    Комментировать
  • Как правильно работать с циклом for?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const currentYear = new Date().getFullYear();
    const years = [];
    for (let year = currentYear - 5; year <= currentYear + 5; year++) {
      years.push(year);
    }
    
    years // [2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027]


    Сейчас у вас ошибка в том, что внутри цикла на каждой итерации, снова и снова newYear сначала делается равным текущему зачем-то. Может, хотели сделать это только один раз, снаружи цикла?
    for (let i = 0; i < 5; i++) {
        let newYear = year; // <--- тут ошибка
        firstYears.push((newYear -= 1));
      }
    Ответ написан
    2 комментария
  • Почему WeakMap и WeakSet могут работать с 1 элементом, но не могут работать сразу со всей коллекцией данных?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Именно чтобы избежать неопределённости «а сработал ли уже сборщик мусора?», у WeakMap отсутствуют методы перечисления его элементов.

    В вашем коде нет смысла после удаления obj — чего ожидаете от weakMap(null)?

    Использование может быть, как приводят пример, в хранении приватных данных объекта или скрытия его реализации.

    Только сам объект, используя себя как известный ключ, может получить из weakMap какие-то припрятанные данные. Нет объекта — нет данных.
    Ответ написан
    Комментировать
  • Как вызвать функцию по имени через call?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если функция объявлена как function UpdateName() { // ... } то можно так:
    this[v].call(null);

    Если объявлена как let или const, то хорошего варианта нет.
    Можно например, через eval(), но это крайне нежелательно:eval(`${v}.call(null)`); — т.е. составляется текстовая строка JS-кода, которая исполняется.

    Почему бы не составить объект с функциями:
    const methods = {
      UpdateName: () => { /* ... */ },
      UpdateAddress: () => { /* ... */ },
    };
    methods[v].call(null);
    Ответ написан
    Комментировать
  • Как работает этот код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Второй аргумент в Array.map() — это thisArg для функции.

    Тут абстрактный от конкретного массива pop() будет вызываться в контексте начального массива nums — последовательно выдирая из него последний из оставшихся элементов: 3, 2, 1
    Массив nums, соответственно, на каждой итерации будет становиться на 1 элемент короче.

    Копия исходного массива [...nums] нужна только ради его первоначальной длины, чтобы вызвать дальнейшую магию правильное число раз.
    Ответ написан
    3 комментария
  • Как вывести большой объем данных на страницу в табличном виде?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Никто не станет читать такое количество данных подряд.

    Нужны:
    Поиск. Фильрация. Сортировки. Пролистывание +1, +10, +100 страниц. В начало, в конец.
    Запоминать историю навигации / фильтрации / сортировки, чтобы можно было несколько раз вернуться «назад».

    Само отображение — рисовать только то, что на экране, плюс, может, небольшой запас вверх-вниз, в несколько строк. По мере прокрутки, переставлять строки, заполняя их новыми данными – т.н. «виртуальная прокрутка» == "virtual scrolling" – распространённая практика, полно готовых компонентов.
    Ответ написан
    2 комментария
  • Как сделать регулярное выражение для положительных и отрицательных чисел?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Регулярка тут не нужна и вредна. Почему бы просто не конвертировать в число и проверять, что в диапазоне?

    document.querySelector('input').addEventListener('input', e => {
      const { value } = e.target;
      const num = Number(value);
      const isValid = !isNaN(num) &&
        num <= 60 &&
        num >= -60;
    
      // что-то делаем с валидным / невалидным
      if (isValid) {
        // мы молодцы, сирену можно выключить
      } else {
        // включаем мигалку и сирены, подсвечиваем красным
      }
    });
    Ответ написан
    Комментировать
  • Почему у функции в setInterval "пишем" одни скобки а не две вызывая ее при замыкании?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Потому, что в setInterval() первым аргументом надо передать функцию (он сам вызовет её потом),
    а «без setInterval» — для получения результата надо эту же функцию ещё и вызвать самим.

    длинный ответ
    Функцию в JavaScript можно «положить в переменную», передать как аргумент при вызове другой функции или получить как результат вызова ещё одной функции. Так же как "строку" или число 42.

    В этом выражении, смотрите, есть не 1, а целых 2 стрелочки:
    (param) => () => {
      console.log("Выхлоп!" + param);
    }
    Две стрелочки, значит, тут две функции. Одна вокруг второй. Первая, та, что снаружи, принимает аргументом param, и возвращает вторую функцию () => { console.log("Выхлоп!" + param); } Причём вернувшаяся функция «запомнила» значение param внешней обёртки и будет его использовать. Это обёртывание называется «Замыкание» или "closure".

    Теперь скобки при вызове. У нас матрёшка из двух функций: function(){ return function() {}; }

    Чтобы вызвать внешнюю, нужны первые скобки: ((param) => () => console.log(param))(6) – этот вызов внешней с аргументом 6 даст результатом внутреннюю функцию, которая запомнила значение param. И мы имеем на руках внутреннюю функцию.

    Чтобы вызвать внутреннюю, нужны вторые скобки: ((param) => () => console.log(param))(6)()

    Итого, две функции — два вызова — две пары скобок.

    В setInterval() первым аргументом надо передать не конечный результат, а функцию — её вызовут через некоторое время, не сразу. Тут передают внутреннюю функцию. Поэтому скобки всего одни: с одними скобками получаем внутреннюю функцию.
    Ответ написан
    1 комментарий
  • Как сделать круговое расположение букв в словах?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Библиотека CircleType (демо)
    Ответ написан
    Комментировать
  • Как сохранять цветовую тему в localstorage?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    при действии пользователя — сохранять в LS выбранное.
    при загрузке страницы — брать значение из LS или если-пусто, подставлять значение по-умолчанию.
    Что именно вызывает ступор?

    Пока там только две настройки: выбранный цвет и день/ночь. Я бы предложил хранить их в виде JSON под одним ключом localStorage. В одном объекте.

    Вообще, сделал бы объект Настроек центром всей затеи )
    В начале берётся или сохранённый в LS, или с дефолтными значениями.
    С помощью Proxy (обёртки) этого объекта, любое изменение любой из настроек сразу сохраняет весь объект в LS и применяет все эти настройки.

    Есть функция, которая получает на вход объект Настроек, и все везде отрисовывает как надо.

    Когда юзер выбирает цвет, день-ночь, или добавите что-то ещё – это действие только меняет настройку в проксированном объекте Настроек. Хитрость в том, что этот объект не простой, а Proxy-обёртка, которая реагирует на каждое изменение: сохраняет его в LS и отрисовывает.

    p.s. да и одинаковые квадраты делать в статичной разметке некруто. Заменил на массив цветов и программную отрисовку одинаковых элементов.


    Песочница
    Ответ написан
    6 комментариев