• Почему for..in не работает для коллекции Map?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Документация (только англоязычная версия) вроде бы, исчерпывающе объясняет:
    The for...in statement iterates over all enumerable properties of an object
    that are keyed by strings
    (ignoring ones keyed by Symbols),
    including inherited enumerable properties.


    Ожидаются свойства-строки. Map заточен под другое и позволяет использовать в качестве ключей что угодно, в том числе объекты. Значения добавленные в Map – это не его свойства в привычном смысле.

    Map, как и «всё в JavaScript» — объект. Поэтому можно взять и назначить ему свои свойства. Вот они вполне себе попадут в перечислёж for..in:
    const m = new Map();
    m.set({}, 'obj');
    m.set('a', 'A');
    
    // это другое
    m.b = 'B';
    
    for (let prop in m) {
      console.log('property', prop);
    }
    
    // property b
    Ответ написан
    Комментировать
  • Где взять минимальный дешевый DBaaS (DB as a Service)?

    В облаке Mail ru (посмотрел) 1800 руб/мес минимальный инстанс MySQL.
    Определённо дешевле можно взять минимальную VPS'ку где-то.
    Ответ написан
    Комментировать
  • Можно ли на маке запустить одновременно одно и тоже приложение скаченное через эпстор?

    Обычное приложение для мака можно запустить несколько раз: в терминале open -n "/Applications/Calculator.app" – каждое выполнение запустит новую копию Калькулятора для примера.

    Но ТС хочется запустить приложение для iOS, какой-то там покер-рум. Приложеньки iOS можно запускать на процессоре M1. Но трюк с множественными инстансами одного приложения — не поддерживается.
    Ответ написан
    2 комментария
  • Делаю SDK. Как объяснить пользователю, иммутабельный геттер или мутабельный?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Объект кота не в курсе требований иммутабельности стейта. Поэтому эти пляски лучше отложить туда же, где требуется иммутабельность.

    Как вариант, использовать immer, чтобы менять глубокие свойства, не беспокоясь об иммутабельности:
    import produce from "immer"
    
    const nextState = produce(this.state, draft => {
      // тут можно всё менять, не беспокоясь об иммутабельности
      const { catValue } = draft;
      catValue.cat.colors = Color.BLACK;
    });
    
    this.setState(nextState);
    или не весь стейт
    import produce from "immer"
    
    const { catValue } = this.state;
    const nextCatValue = produce(catValue, draft => {
      // тут можно всё менять, не беспокоясь об иммутабельности
      catValue.cat.colors = Color.BLACK;
    });
    
    this.setState({ catValue: nextCatValue });
    Ответ написан
  • Что лучше, развернуть фронтенд и бакенд на одном домене или разных субдоменах?

    sergiks
    @sergiks Куратор тега Веб-разработка
    ♬♬
    находясь на едином домене, фронт и бэк беспричинно оказываются «связаны» как минимум общей точкой входа.

    Если их развязать, разместив на разных поддоменах, это позволит, например, независимо переезжать с сервера на сервер только бэку; или перенести статичный фронт на CDN, не трогая бэк.
    Ответ написан
    Комментировать
  • Как скопировать прослушиватели событий с одно элемента на другой без jquery?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    cloneNode() сработает только если слушатели прописаны прямо в атрибутах элемента <a onclick="alert('Habr')">click me</a>

    Слушатели, добавленные элементу через addEventListener() скопировать можно примерно никак.

    Так что лучше держать обработчик отдельно, и навешивать их на элементы по мере надобности:
    function myClickHandler(event) {
      // что-то сделать по поводу клика
    }
    
    element1.addEventListener('click', myClickHandler);
    element2.addEventListener('click', myClickHandler);
    element3.addEventListener('click', myClickHandler);

    Или же слушать события выше по дереву, на общем родителе:
    <div id="parent">
      <button>1</button>
      <button>2</button>
      <button>3</button>
    </div>
    и слушать клики на div#parent
    Ответ написан
    Комментировать
  • Как добавить элемент в массив в объекте react?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const { duration } = filter;
    
    setFilter({
      ...filter,
      [ ...duration, 1, 2, 3 ], // добавили в массив 1, 2 и 3
    });
    
    // теперь state станет
    // { type:"", duration: [1, 2, 3] }
    Ответ написан
  • Что происходит на этих строчках?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    поцитирую документацию:
    Для того, чтобы объект был итерируемым, в нем должен быть реализован метод @@iterator, т.е. этот объект (или любой из объектов из его prototype chain) должен иметь свойство с именем Symbol.iterator:
    Свойство: [Symbol.iterator]
    Значение: Функция без аргументов, возвращающая объект, соответствующий iterator protocol.


    Метод может вернуть объект типа { next() { /* ... */ }}, или, как в вашем примере, метод next() определён на самом объекте, поэтому возвращается this.

    Подробно именно ваш пример расписан на learn.javascript
    Ответ написан
  • Как выбрать объекта с наивысшем свойством из коллекции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    [...Collection.values()].sort((a, b) => a.guild.raw - b.guild.raw).pop()

    Я так понял, дан объект Map. Привести его значения к массиву. Отсортировать по значению guild.raw по возрастанию. Взять последний объект – он с наибольшим значением raw.

    Это не самый эффективный способ: проделывается много ненужных сравнений. Запись короткая, других преимуществ нет.

    Правильнее один раз пройти по массиву, откладывая элемент с наибольшим значением на каждом шаге. Что-то типа
    [...Collection.values()]
      .reduce((max, current) => max.guild.raw > current.guild.raw ? max : current)
    Ответ написан
    Комментировать
  • Почему у стрелочной функции из объекта контекст виндоу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    На learn.javascript, например, неплохо написали:
    Стрелка => ничего не привязывает. У функции просто нет this.
    При получении значения this – оно, как обычная переменная, берётся из внешнего лексического окружения.


    В вашем примере с литералом объекта можно добавить для понимания:
    const obj = {
      w() {
        console.log('w', this);
      },
      x: function () {
        console.log('x', this);
      },
      y: this,
      z: () => {
        console.log('z', this);
      },
    };
    
    obj.w(); // obj
    obj.x(); // obj
    console.log('y', obj.y); // Window
    obj.z(); // Window


    Запись литерала объекта не создаёт свой контекст: на момент записи this тот же, что и снаружи:
    const a = this; // Window
    const obj = {
      b: this, // тоже Window 
    }
    
    a === obj.b // true
    Ответ написан
    1 комментарий
  • Возможно ли получить ссылку на текущую функцию изнутри функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    arguments.callee, но это свойство недоступно в strict mode. В частности, в модулях.

    Ну, или просто дайте функции имя, чего жадничать-то : )
    (function toster() {
      console.log(toster);
    })();
    Ответ написан
    1 комментарий
  • Насколько сложна эта задача?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если дочитали документацию JavaScript до Set, то решение совсем простое: перевести массив в сет (останутся только уникальные значения), и сет обратно в массив.

    upd. неправильно понял задачу. Если надо вернуть только элементы, которых в исходном массиве ровно 1 штука, то надо видимо считать. Сделать объект, где ключи строки, значения число, сколько раз нашлись. { "кришна": 4, "харе": 4, ":-O": 1 }Оставить только те, где значения 1. Собрать в массив.

    Или оставить те, что с начала и с конца находятся только «здесь и сейчас»:
    const unique = arr => arr.filter((item, i) => i === arr.indexOf(item) && i === arr.lastIndexOf(item));
    Ответ написан
    Комментировать
  • Как каждый раз отправлять новый элемент массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    заведите переменную счётчик:
    let offset = 0;
    async function requestAndTreatment() {
      // ...
      const point = res.data[offset++];
      data.addData([[res.timestamp, point.open, point.high, point.low, point.close]]); 
    }

    вообще перепроверьте логику: мне кажется странным, что из данных API вы хотите с каждым разом брать следующую позицию. Как будто они одни и те же каждый раз. А как до конца дойдёте, что дальше?
    Ответ написан
  • Как сделать, чтобы работали все кнопки лайка?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    main.querySelectorAll('.element__button')
      .forEach(el => el.addEventListener('click', () => el.classList.add('element__button_active')));
    Ответ написан
    1 комментарий
  • Как обновить значение в object?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если задача иметь каждый раз «актуальные» секунды,
    наверное, стоит сделать геттер для свойства second,
    который каждый раз будет вычислять значение:
    const timerObject = {
      DATE: new Date(),
      listDATE: {
        get second() {
          return new Date().getSeconds();
        },
      },
    };
    
    // читать, как обычно
    console.log( timerObject.listDATE.second );
    
    // через секунду
    setTimeout(() => console.log( timerObject.listDATE.second ), 1000); // на 1 больше

    Сеттер вроде при этой задаче и не требуется. Просто хочется получать каждый раз актуальное значение?
    Ну или ещё проще, сделайте просто метод:
    const timerObject = {
      DATE: new Date(),
      listDATE: {
        second: () => new Date().getSeconds(),
      },
    };
    
    // использование
    console.log( timerObject.listDATE.second() );
    Ответ написан
    1 комментарий
  • В чём ошибка в задаче?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Три подсказки.

    Проверить, что аргумент является строкой:
    typeof arg === 'string'
    // ещё можно длину проверить, а то, вдруг длинное пришлют
    arg.length === 1

    Проверить, что это буква и есть пара в другом регистре:
    arg.toLowerCase() !== arg.toUpperCase()
    // строка перевелась в разные кейсы

    В каком кейсе изначально была буква:
    arg.toUpperCase() === arg // значит, буква в верхнем регистре


    Из этих кирпичиков остаётся сложить домик. И чтоб не рухнул )
    Ответ написан
    1 комментарий
  • Как следить за статусом контейнеров?

    Если без внешних инструментов с бесплатным триалом и деньжищами за использование,
    можно через Docker API получать живой стрим событий. Отфильтровать в нём только интересующие, например, container=<string> когда имя интересующего контейнера известно и постоянно.

    Но вообще присмотритесь подробнее к опции restart – пусть контейнер перезапускается автоматом после падения. И может, при запуске как-то куда-то отправляет «Доброе утро, админ!»
    Ответ написан
    Комментировать
  • Не понимаю, как это работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Просто прочитайте документацию или ещё что-то про сортировку.

    Вопрос «что здесь принимается за a, а что за b?» не самый удачный: в примере аргументы игнорируются.
    В этом странном коде возвращается всегда отрицательное число. Значит, результат сортировки массива зависит только от внутренней реализации — от того, в каком порядке будут сравниваться пары элементов.
    Ответ написан
  • Как динамически импортировать изображение?

    Модули импортируются статически, ещё до выполнения любого кода.

    Есть вариант динамического асинхронного импорта import(moduleName). Но у этого способа главный недостаток: WebPack соберёт в отдельный чанк все файлы с флагами, и бандл будет тяжеловат.

    Если хочется красоты, можно заморочиться и дописать модуль, где прописаны импорты и тут же экспорты всех флагов. Типа
    import ru from "svg-country-flags/svg/ru.svg";
    import ua from "svg-country-flags/svg/ua.svg";
    // ...
    
    // и там же экспорты:
    export ru;
    export ua;
    // ...

    Тогда достаточно будет одной строкой импортировать нужные флаги import { ru, ua } from './mySuperModule';И Webpack разберётся и включит в бандл только нужное.

    Когда напишете такой вспомогательный модуль, отправьте, пожалуйста, pull-request в тот репо.
    Ответ написан
    Комментировать
  • Как JS проверить на пустоту или создание объекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    элемент же может и отсутствовать?

    Тогда document.querySelector("#******") вернёт undefined, и попытка получить из него свойство innerText выкинет ошибку. Загляните в консоль.

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

    Что-то типа
    const el = document.querySelector("#******");
    if (el) {
      const a = el.innerText;
      if (a.length === 0) {
        el.value = "123"; // а что это за элемент, у которого и innerText и value ?
      }
    }
    Ответ написан
    Комментировать