Задать вопрос
Ответы пользователя по тегу JavaScript
  • Как после загрузки файлов в инпут files получить доступ к каждому отдельно?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    File унаследован от Blob, а значит с File можно делать все, что и с Blob, в том числе добавлять его в FormData через append или получать на него ссылку через URL.createObjectURL.
    И да, FileReader на самом деле тоже работает с Blob.

    Ну и ловите пример, близкий к Вашей задаче: https://developer.mozilla.org/en-US/docs/Web/API/F...
    Ответ написан
    Комментировать
  • Как узнать последнюю цифру числа?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Для целых чисел все просто, как уже верно заметил Stalker_RED достаточно взять остаток от деления на 10n % 10
    Но вот с дробными числами все намного интереснее. Потенциально, можно получить целое представление последовательно умножая число на 10 (сдвигая тем самым десятичную точку вправо), а после воспользоваться предыдущим приемом. Но проблема тут в том, что потенциально такая последовательность может оказаться бесконечной и такой алгоритм зациклится.
    Если обратится к стандарту IEEE 754, то можно узнать, что в 64 битах можно точно представить не более 16 десятичных разрядов, а это уже можно использовать как ограничитель, так как при превышении 16 сдвигов десятичной точки значение все равно уже не будет точным
    const lastDigit = n => {
        // в n совсем не то
        if (isNaN(n) || !isFinite(n)) return NaN;
        // в n целое
        if (n % 1 === 0) return n % 10;
        // для дробных проще со строкой работать
        const s = String(Math.abs(n));
        // неточные значения
        if (s.length > 16 || s.includes('e')) return NaN;
        return +s.slice(-1);
    }
    Ответ написан
    Комментировать
  • Загрузка картинок при скролле?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Почему profit равен "1"?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Пройдите свой код по шагам и сразу увидите, что keys - пустой массив
    А reduce на пустом массиве просто возвращает init значение, даже не заходя в колбэк
    Ответ написан
    Комментировать
  • Как работают циклы с таймаутом?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Первое что нужно понять, таймер работает асинхронно, а значит будет выполнен после цикла.
    Второе - let имеет блочную область видимости (переменная видна в том блоке, где была объявлена, при этом первый операнд for считается тем же блоком, что и тело цикла)
    Третье - циклы создают новый скоуп на каждую итерацию (на каждой итерации будет свой let i, при условии что этот оператор внутри цикла)

    Ну и еще, в Ваших примерах 1000 относится не к таймауту, это просто бесполезная операция, а таймаут получит значение по умолчанию - 0, думаю это не совсем то, что Вы ожидаете.

    Еще один важный момент, функциональное выражение (а стрелочная функция - это тоже функциональное выражение) внутри цикла будет создавать по функции на каждой итерации цикла. Это очень плохо и по памяти и по производительности (такие функции еще и компилироваться и оптимизироваться будут раздельно). И если в случае с let внутри цикла функции хотя бы будут отличаться замыканием (каждая замкнет свою i), то в первом случае будет 5 абсолютно идентичных функций.
    Тут можно очень хорошо показать себя, если помимо объяснения принципов работы вспомнить, что setTimeout умеет передавать аргументы в свой колбэк:
    const f = i => {
      console.log(i);
    };
    for (let i = 0; i < 5; i++) {
      setTimeout(f, 1000, i);
    }
    Ответ написан
    Комментировать
  • Async: false; - плохая практика?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    В браузере в одном потоке выполняется и Ваш JS и интерфейс пользователя и много чего еще. И если Вы заблокируете этот поток длинными вычислениями или еще чем-то, то все это встанет. Для пользователя вкладка зависнет. Не будут работать ни ссылки, ни кнопки, даже закрыть ее привычными способами будет проблематично.
    Синхронный запрос блокирует поток на время всей отправки запроса и получения ответа, притом именно так, поочереди, ибо враз тут опять не выйдет. Добавьте сюда еще то, что сеть обычно штука медленная.

    mutation observer ловит изменения, делает проверку и заполняет массив потоми делает запрос. Но тут почему то ajax не ждёт пока заполнится массив и сразу выполняет запрос.
    К тому же эту проблему синхронный запрос не решит, он ее наоборот усугубит, так как MutationObserver так же не сможет отработать пока не завершится запрос.

    Существуют ли случаи, когда оправдано использование синхронных запросов
    единственное оправданное применение - отправка данных перед закрытием вкладки на динозаврах без поддержки sendBeacon
    Заметьте, в современном fetch api даже нет такой возможности, как отправка синхронного запроса, и не просто так.

    логика хромает и лучше всего все переписать
    к сожалению появление асинхронности в одном месте может привести к появлению асинхронности во многих других местах, по другому ни как. Так что да, придется переписать. Но это неизбежно, так как многие api в современно браузере (тот же MutationObserver) работают только асинхронно. К счастью есть промисы и async/await сахар над ними, что сильно упрощает такую задачу.
    Ответ написан
    1 комментарий
  • Как преобразовать объект в URI?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://developer.mozilla.org/ru/docs/Web/API/URLS...
    https://developer.mozilla.org/ru/docs/Web/API/URL/URL
    const OBJECT = {
      fields: {
        NAME: 'LOREM',
        SECOND_NAME: 'IPSUM',
        LAST_NAME: 'DOLOR',
      }
    };
    const url = new URL('https://somesite.com/crm.contact.add.json');
    for (const [name, value] of Object.entries(OBJECT.fields)) {
        url.searchParams.append(`fields[${name}]`, value);
    }
    console.log(url.href);
    Ответ написан
    Комментировать
  • Фильтрация объекта в JS?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Как осуществить перебор такого массива?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://developer.mozilla.org/ru/docs/Web/JavaScri...

    ну и оторвать руки тому, кто нагородил такого уродца
    Ответ написан
    Комментировать
  • Как запретить отключения линтера через инлайн комментарии?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Помимо полного отключения управляющий комментов, как предложил Uneasy Hearts Weigh the Most, их можно контролировать тем же eslint: https://www.npmjs.com/package/eslint-plugin-eslint...
    Ответ написан
    Комментировать
  • Как сделать вывод сообщений с сортировкой по дате как в телеграмм?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const sortedArr = arr
        .map(({date, ...rest}) =>
            ({...rest, date: new Date(date)}))
        .sort(({date: a}, {date: b}) =>
            b - a);
    console.log(sortedArr)
    Ответ написан
  • Какие на самом деле типы данных в javascript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Как я понимаю в js два основных типа данных

    Согласно спеке в JS есть 8 типов данных:
    • object - все объекты и функции (в реальности во всех имплементациях у функций свой тип function)
    • string - строки
    • boolean - логические значения (true и false)
    • number - числа с плавающей запятой двойной точности (в других языках это double или float64)
    • bigint - целые числа (int64) с поддержкой длинной арифметики
    • symbol - спец тип, каждое значение которого уникально
    • undefined - юнит тип с единственным значением undefined, значение по умолчанию во многих случаях
    • null - юнит тип с единственным значением null (в реальности во всех имплементациях null имеет тип object), задумывался и используется как аналог null pointer/null reference в других языках


    Что происходит с типом данных когда str конкатинируется со строкой 'Vova' ?
    с типом данных ничего не происходит. Значение получается новое, по крайней мере так должно быть согласно спеке и так все выглядит для рядового js разработчика.
    На самом деле самый распространенный js движок v8 именно со строками делает под капотом разную магию, зная, что строки никогда не меняются он умеет их представлять в виде массива срезов (множества кусочков лежащих в разных местах), избегая тем самым дорогого копирования памяти. В данном примере result будет состоять из двух срезов, которые указывают на представление кода в памяти, притом первый кусок будет указывать на ту же память что и str. Но если result "доживет" до момента, когда сборщик мусора будет делать дефрагментацию памяти, то после нее он уже будет указывать на целую самостоятельную строку.

    Вопрос вот в чем, так ли примитивы перезаписываются если с ними выполняются какие-то операции? Меня интересует сам алгоритм создания, что происходит внутри
    Примитивы никогда не перезаписываются, по крайней мере пока они "живы" (пока сборка мусора не признает их мусором в виду отсутствия ссылок на память где они лежат). Все манипуляции с переменными под капотом почти всегда (о том когда нет - напишу ниже) являются простыми манипуляциями над указателями (ссылками).

    Являются ли примитивные типы объектами?
    С точки зрения спеки - нет, не являются. У них должны появляться объектные обертки в момент обращения к их полям (через точку или квадратные скобки).
    На деле, если сделать как в спеке - все будет жутко тормозить. Поэтому в v8 почти все является объектом (правда не совсем таким, как мы видим объекты со стороны js), а соблюдение спеки для примитивных типов достигается через иммутабельность.
    Исключением являются null и undefined, у которых нет ни полей, ни прототипа. Для них хранится только информация о типе.
    Так же после оптимизаций jit компилятора числа могут избавится от объектных оберток, когда оптимизируемый код их не использует, тем самым избавляясь от разыменовывания указателя, при этом bigint может превратится в int64, а number в float64 или int32 в зависимости от использования. Так же, массивы состоящие только из чисел одного типа могут быть сведены к настоящим массивам из чисел, но этого эффекта можно достичь и до оптимизаций, если использовать типизированные массивы.
    Ответ написан
    3 комментария
  • Как при нажатии на select > option открыть элемент?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://developer.mozilla.org/en-US/docs/Web/API/H...
    Нужно отслеживать change на select
    option, на сколько помню, вообще не кидают событий
    Ответ написан
    Комментировать
  • Как сделать обработку жеста "зум двумя пальцами" на тачскринах на JavaScript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Можно и без библиотек:
    https://developer.mozilla.org/ru/docs/Web/API/Touc...
    https://developer.mozilla.org/ru/docs/Web/API/Touc...
    https://developer.mozilla.org/ru/docs/Web/API/Touc...
    https://developer.mozilla.org/en-US/docs/Web/API/T...

    В TouchList каждый элемент - это палец. По изменениям координат в последовательных события touchmove можно построить векторы движения.
    Усредняем эти векторы до 1/4 или 1/8 долей окружности с общим центром для всех векторов, если 2 пальца движутся в противоположных долях - это зум, навстречу друг другу - уменьшение, а от друг-друга - увеличение.
    Ответ написан
    Комментировать
  • Как работать с IndexedDB из класса?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://developer.mozilla.org/ru/docs/Web/JavaScri...
    100 раз уже это спрашивали...
    Научитесь работать с асинхронным кодом...
    Ответ написан
  • JS выдает разный контекст при разном способе вызова функций, как с этим работать?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://developer.mozilla.org/ru/docs/Web/JavaScri...

    addEventListener, кстати, может принимать не только функции, но и объекты с методом handleEvent, и в нем this будет указывать на переданный объект
    https://developer.mozilla.org/ru/docs/Web/API/Even...
    Ответ написан
    Комментировать
  • Какое практическое применение для функции генератора?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Генератор - это императивно управляемый итератор. Сами итераторы позволяют производить ленивые вычисления.

    Практическое применение например в том, что можно построить высокоуровневые абстракции над итераторами:
    function* counter() {
      let i = 0;
      while (true) {
        yield i++;
      }
    }
    
    function* map(innerIterator, f) {
      for (const value of innerIterator) {
        yield f(value);
      }
    }
    
    function* filter(innerIterator, f) {
      for (const value of innerIterator) {
        if (f(value)) {
          yield value;
        }
      }
    }
    
    function* take(innerIterator, count) {
      let i = 0;
      for (const value of innerIterator) {
        yield value;
        if (++i === count) { return }
      }
    }
    
    function* inspect(innerIterator) {
      for (const value of innerIterator) {
        console.log(value);
        yield value;
      }
    }
    
    console.log('Создаем итератор');
    const iter = inspect(
      take(
        map(
          filter(
            counter(),
            v => v % 2 === 0
          ),
          v => v * 2
        ),
        30
      )
    );
    console.log('Итератор есть, но он еще ничего не считает: ', iter);
    console.log('Вычисления будут по требованию:');
    console.log([...iter]);
    Ответ написан
  • Чем JavaScript абстрактнее других языков программирования?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    На JS можно спокойно писать (и очень многие пишут) вообще не задумываясь где и как у Вас выделяется память и где и когда она освобождается. И программа будет работать, возможно даже без багов и утечек.

    В JS Вам не нужно думать, о том сколько живут объекты, если у Вас есть ссылка - объект точно жив.

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

    В JS у Вас никогда не будет Undefined Behavior.

    В JS у Вас никогда не будет гонок данных, каждый поток (воркер) живет в своем пространстве памяти. И даже если Вы пошарите память, Вам не придется парится с атомиками/мьютексами и c memory order, все уже решили за Вас.

    В C++ Вам придется об этом всем думать, если захотите написать что-то полезное.
    Ответ написан
    2 комментария
  • Как правильно присвоить класс?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const mediaQuery = window.matchMedia('(max-width: 992px)');
    const handler = () => 
        $(document.body).toggleClass('lock', mediaQuery.matches);
    mediaQuery.addListener(handler);
    handler();

    https://developer.mozilla.org/ru/docs/Web/API/Wind...

    А вообще, такое спокойно через CSS можно делать:
    @media (max-width: 992px) {
        body {
            /* тут то что у Вас в .lock было */
        }
    }
    Ответ написан
    2 комментария