Ответы пользователя по тегу JavaScript
  • Как передавать параметры в url?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Без перезагрузки можно менять хэш:
    function addFilter(filter) {
      const delimiter = ',';
    
      // разобрать хэш
      const str = location.hash;
      const hashes = str.slice(str.indexOf('#') + 1).split('&')
      const params = {}
      hashes.forEach(hash => {
        if (!hash) return;
        const [key, val] = hash.split('=')
        params[key] = decodeURIComponent(val)
      })
    
      // параметр фильтров разобрать, добавить, собрать
      const filters = params.search ? params.search.split(delimiter) : [];
      filters.push(filter); // ["Toster", "Habr"]
      params.search = filters.join(delimiter);
    
      // собрать обратно
      hashes.length = 0;
      for (p in params) 
        hashes.push([p, encodeURIComponent(params[p])].join('='));
      
      location.hash = '#' + hashes.join('&');
    }
    
    addFilter('Toster');
    addFilter('Habr');
    //#search=Toster%2CHabr
    Ответ написан
    Комментировать
  • Можно ли при объявлении объекта сослаться на другие его поля?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Тиражируемое значение в переменную заранее:
    const value = 1 + 1 * 1;
    var a = {
      b: value,
      b1: value
    }

    Вопрос возник из-за чего: некрасиво как-то в коде выглядит повтор, или не хочется одну строку добавить, как предложил dollar ? Или есть задача обработки назначаемых данных – видели сеттеры / геттеры?
    // хочется так? (но нельзя!)
    var a = {
      b: 1,
      c: this.b * 10
    }
    
    // тогда можно так:
    var a = {
      get c() { return this.b * 10; }
    }
    a.b = 1;
    
    a.c // 10
    Ответ написан
    7 комментариев
  • Как правильно передать аргумент в функцию?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В первом случае останется ссылка на объект, будет занимать память (ой, как много!), пока весь код не отработает.
    Внутри функции можно поменять свойства объекта, если это интересно:
    function testFunction(name, data) {
      data.param1 = name;
    }
      
    const obj = {
      param1: 1,
      param2: 2
    }
    testFunction('test', obj);
    
    obj.param1 // "test"
    Ответ написан
    2 комментария
  • Как получить весь список дней в году вида 03/10/2019?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надо создать объект Datе в текущем году, установить его на 1-е января setDate(1), setMonth(0) и прибавлять по 1 дню. Месяца перевернутся автомагически.

    Для форматирования mm/dd/yyyy можно использовать локальный формат дат для США, указав в опциях, что даты и месяц выводить как 2-цифры.
    const dates = [];
    const options = { year: 'numeric', month: '2-digit', day: '2-digit' };
    const d = new Date();
    d.setMonth(0);
    d.setDate(1);
    const year = d.getFullYear();
    while(d.getFullYear() === year) {
      dates.push(d.toLocaleDateString('en-US', options));
      d.setDate(d.getDate() + 1);
    }
    
    /*
    01/01/2019
    01/02/2019
    01/03/2019
    01/04/2019
    01/05/2019
    01/06/2019
    01/07/2019
    01/08/2019
    01/09/2019
    01/10/2019
    ...
    */
    Ответ написан
    1 комментарий
  • Как менять div взависимости от выбора Option в Select?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Ответ написан
    Комментировать
  • Как коротко переписать lodash функцию fill?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вы же смотрели исходники lodash'евской реализации? baseFill() и fill() У них топорно:
    while (start < end) {
        array[start++] = value;
    }

    Пропустили возможность отрицательных индексов.
    Полагаетесь на возможно отсутствующую поддержку ES6 – все эти Array.fill(), ...filler
    Ответ написан
  • Последний ответ от асинхронной функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Возможно, костыль, но можно в переменную записывать по окончании очердной асинхроты, кто она такая. Соотв. последний записавший остаётся в этой переменной, а всех их пачкой в Promise.all()

    Если бы функции asyncX() возвращали промисы:
    const yourXFunction = (async1, async2, async3, someCallback) => {
      let latest; // последнее значение остаётся
      Promise.all([
        async1().then(v => {latest = 1; return v;}),
        async2().then(v => {latest = 2; return v;}),
        async3().then(v => {latest = 3; return v;}),
      ]).then(results => {
        console.log("Last was async" + latest);
        someCallback(results[latest - 1]);
      });
    }


    Рабочий код
    const yourXFunction = (async1, async2, async3, someCallback) => {
      let latest; // последнее значение остаётся
      Promise.all([
        wrap(async1).then(v => {latest = 1; return v;}),
        wrap(async2).then(v => {latest = 2; return v;}),
        wrap(async3).then(v => {latest = 3; return v;}),
      ]).then(results => {
        someCallback(results[latest - 1]);
      });
    }
    
    const wrap = (f) => new Promise((res, rej) => f(res));
        
    const async1 = (cb) => {
        setTimeout(() => {
            cb(1);
        }, 4000);
    };
    const async2 = (cb) => {
        setTimeout(() => {
            cb(13);
        }, 6000);
    };
    const async3 = (cb) => {
        setTimeout(() => {
            cb(5);
        }, 3000);
    };
    const someCallback = (val) => console.log(val);
    
    yourXFunction(async1, async2, async3, someCallback);
    // через 6 секунд выведет "13"
    Ответ написан
    Комментировать
  • Как преобразовать строку в объект?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Проблема в (как это по-русски?) escaping:
    // так не сработает:
    const response = '{"success":1,"data":"{\"esiaId\":null,\"legalMunicipality\":{\"id\":12,\"name\":\"Энгельс\"},\"factMunicipality\":{\"id\":12,\"name\":\"Энгельс\"},\"is_subscribed\":false,\"subscriptions\":null}"}';
    
    // а вот так всё получится:
    const response2 = '{"success":1,"data":"{\\\"esiaId\\\":null,\\\"legalMunicipality\\\":{\\\"id\\\":12,\\\"name\\\":\\\"Энгельс\\\"},\\\"factMunicipality\\\":{\\\"id\\\":12,\\\"name\\\":\\\"Энгельс\\\"},\\\"is_subscribed\\\":false,\\\"subscriptions\\\":null}"}';
    console.log(response2);
    const parsed = JSON.parse(response2);
    const data = JSON.parse(parsed.data);
    console.log(data.legalMunicipality.name); // Энгельс
    Ответ написан
  • Работает код на чистом js быстрее чем jquery?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    jQuery написан на всё том же чистом JavaScript, но добавляет тяжёлый довесок для удобства.

    Можно написать реализацию вашего алгоритма с использованием и без использования jQuery и сравнить на миллионе прогонов на сайте jsPerf – и другие смогут повторить ваши тесты на их компьютерах/браузерах, ведь от этого тоже многое зависит.
    Ответ написан
    Комментировать
  • Хранение параметров сайта без PHP, такое возможно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Придется подключать внешний сервис. Например, от Google. И чтобы что-то сохранить, придётся авторизовываться через них.
    Ответ написан
    Комментировать
  • Как сделать функцию разбивки массива на массивы более коротко?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Гуглили? Например, несколько вариантов решения (см. комменты).
    Ответ написан
    Комментировать
  • Как сравнивать массивы в постоянно увеличивающейся цепочке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Тут поможет Map! Словарь, где ключами может выступать не обязательно строка, а вообще любой тип данных JS.

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

    const someObject = {a:'value A'};
    const arr1 = [1, 'test', someObject];
    const arr2 = [100, 200, 'testing', {a:'value A'}];
    const arr3 = [1e3, someObject];
    const arrays = [arr1, arr2, arr3];
    
    const dict = new Map();
    
    const addArray = (arr, label) => {
      for(let i=0, len=arr.length; i<len; i++) {
        const key = arr[i];
        if (dict.has(key)) return [key, dict.get(key), label];
        dict.set(key, label);
      }
    }
    
    for (let i=0, len = arrays.length; i<len; i++) {
      const check = addArray(arrays[i], `arr${i+1}`);
      if (!check) continue;
      console.log(`Value ${check[0]} found in arrays ${check[1]} and ${check[2]}`);
      break;
    }
    // Value [object Object] found in arrays arr1 and arr3
    Ответ написан
    Комментировать
  • Вопрос с собеседования - почему не меняется объект?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Добавить можно было бы про способы достичь желаемого: обнулить массив внутри объекта.
    Через splice(), .length=0 и т.п.
    Ответ написан
    Комментировать
  • Как сделать таймер (в формате mm:ss) допустим 00:60?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Держите


    [Disclaimer] это пример для возбуждения любопытства к программированию. Таймер не остановится при достижении времени Ч и продолжит тикать в минус.
    Ответ написан
    Комментировать
  • Нужно ли использовать iife?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    С появлением в ES6 let и const – объявлений с блочной областью видимости – без IIFE можно обходиться там, где их заводили только ради чистоты глобальной о.в.:
    // раньше
    (function(){
      var a = 1;
      var b = 2;
      b *= 2;
      console.log(a + b);
    })();
    // здесь a и b уже не видны
    
    
    // теперь можно просто заключить часть кода в "блок"
    // и все переменные останутся в Вегасе:
    {
      const a = 1;
      let b = 2;
      b *= 2;
      console.log(a + b);
    }
    Ответ написан
    3 комментария
  • Как работает функция случайного числа от min до max?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Math.random() возвращает псевдослучайное с равномерной вероятостью в диапазоне от 0 до 1. Включая 0, исключая 1. Такой интервал ещё можно записать как [0, 1) — квадратная скобка означает включение числа, круглая – «дырку», исключение.

    Math.round() округляет дробные до «ближайшего» целого. От x - 0.5 (включая) до x + 0.5 (исключая) округлит до целого x. Можно записать так: [x-0.5, x+0.5)

    Функция получения случайного целого в диапазоне от min до max в описанном варианте старается сгладить вероятности всех целых до равных.

    Визуально это представить так: насыпается «дорожка» поваренной соли на диапазон от 0 до 1 – это равномерно распределённые вероятности из Math.random(). При этом сама "1" не участвует, но в данном случае это маловажно. Далее умножаем да диапазон, напр. на 4, и с помощью Math.round() делим отрезки этой дорожки в кучки для каждого целого. Кучки по краям получатся меньше остальных.

    Если случайное [0, 1) просто умножить на 4 и округлить Math.round() – будет выдавать случайные целые [0, 4] (а не до 3). И как неравновероятно!
    0                   1
    [...................)
    
    0    1    2    3    4
    00011111222223333344o


    Из-за того, что Math.round() разбивает пополам расстояние между двумя целыми, получится не 4 а 5 кучек. При чём в крайние, 0 и 4, попадёт всего по пол-интервала. Их вероятность будет 1/2 от полноценных вероятностей для 1, 2 и 3.

    Поэтому, в данной реализации генерируют от min-0.5 до max+0.5, чтобы после Math.round() вероятности всех целых были одинаковы.

    P. S. за эту размазанность Math.round() можно недолюбливать и вместо него округлять вниз, Math.floor() – так случайное целое, как в вашем вопросе, можно получить проще
    const rand = (min, max) => min + Math.floor(Math.random() * (max - min + 1));
    alert( rand(1, 3) );

    Кстати, в программировании часто предпочитают иметь дело с интервалами [ .. ) – включающими начало, но исключающими конец. Например, randomInteger(min, max) никогда бы не вернула max. А это задание вышло такое себе, нетрадиционное, у них )
    Ответ написан
    1 комментарий
  • Что значит " _ " в следующей arrow function: _ => store.shift()?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Так записывают неиспользуемую переменную.

    Когда в функции не требуется аргумент, экономят 1 символ, чтобы не писать, как положено:
    () => somecode;

    Линтер такой юмор не оценит и будет ругаться.
    Ответ написан
    1 комментарий
  • Авторизация через VK на клиенте?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Два разных варианта авторизации пользователя в ВК:
    • Implicit flow. Для работы с API от имени пользователя в Javascript-приложениях и Standalone-клиентах (десктопных или мобильных).
    • Authorization code flow. Для работы с API от имени пользователя с серверной стороны Вашего сайта.


    Сейчас у вас реализован 2-й. А хотите 1-й.
    Ответ написан
    Комментировать
  • Можно ли на js сделать такой таймер?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Получите число миллисекунд от текущего момента до времени «Ч»:
    const che = new Date(2020, 0, 1);
    const now = new Date();
    let diff = Math.floor((che - now) / 1000); // в секундах


    Теперь от общего к частному. Дни - часы - минуты - секунды.
    Сначала число дней. В сутках 24 * 60 * 60 = 86400 секунд.
    const days = Math.floor(diff / 86400);
    // вычесть учтённые дни из остатка времени
    diff -= days * 86400;


    Далее так же с часами, минутами, остаток – секунды.

    И, высший пилотаж, изменять подпись в заисимости от числа:
    0 – дней – часов
    1 – день – час
    2 – дня  – часа

    Например, такой функцией:
    function declOfNum(number, titles) {  
        cases = [2, 0, 1, 1, 1, 2];  
        return titles[ (number%100>4 && number%100<20)? 2 : cases[(number%10<5)?number%10:5] ];  
    }
    
    // применение:
    declOfNum(days, ['день', 'дня', 'дней']); // массив из вариантов для 1, 2, 5
    Ответ написан
    Комментировать
  • Как сделать замену четных чисел на 0?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    function func_9() {
      let k = +prompt('Введите первое число');
      let i = +prompt('Введите второе число');
      if (k > i) {
        while (k > i) {
          if (k % 2 == 0) {  // это значит, что k четное - выведите 0
            k--;
            
          } else { // сюда попадаем если k нечетное, надо его просто вывести
            k += + k;  // тут ошибка: зачем-то k удваивается: к нему прибавляется оно же. Эта строка не нужна
            console.log(k); // ок
          }
          k--;
          console.log(k); // не надо
        }
      }
      else {
    // предупредите, что первое число вы ожидаете бОльшим, чем второе. Хотя логичнее просить вводитб первое число меньше, чем второе
        alert('arror');
      }
    }
    
    func_9();


    spoiler
    function funk_it_up() {
      const a = +prompt('Введите первое число');
      const b = +prompt('Введите второе число');
      if (a >= b) {
        alert('Первое число должно быть меньше второго');
        return;
      }
       
      for (let i = a + 1; i < b; i++) {
        console.log( i & 1 ? i : 0);
      }
    }
    
    funk_it_up();
    Ответ написан
    2 комментария