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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вопрос не вполне однозначно сформулирован, но если требуется работать именно с текстовым именем выбранной функции, то можно обращаться к свойству контекста:
    function test(a, b, funcName) {
      let c = a+b;
      if (typeof this[funcName] === "function") this[funcName]();
      else throw `No such function ${funcName}`;
      return c;
    }
    
    function multiplication() {
      console.log("multiplication!");
    }
    
    test(2, 3, 'multiplication'); // выведет multiplication!
    test(6, 4, 'division'); // выкинет ошибку, бо нет такой функции
    Ответ написан
    Комментировать
  • Рассчитать количество элементов, которое поместится в коробку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    по-английски задача называется bin packing problem, считается NP-полной.

    Гуглится можество реализаций, например olragon/binpackingjs
    Ответ написан
    Комментировать
  • Почему js выдает не верный ответ на булевое выражение?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сейчас в обеих переменных — текст, а не числа. Т.к. в алфавите "5" идёт после "4", то "5" > "499999"
    // замените
    var bal = $.trim($('#bal').val());
    // на
    var bal = +$.trim($('#bal').val());

    Аналогичным образом надо поступить и с переменной cl – сделать из текста число.

    Но тут есть ещё другая ошибка.
    В этом коде вы же не расчитываете, что в переменной cl окажется свежий результат выполнения ajax-запроса?
    var cl1 = $.ajax({
                        url: "ajaxs.php",
                        data: "x=test",
                        type: "POST",
                        success: function (data) {
                            window.test1 = data;
                        }
                    });
                    var cl = test1;
    Ответ написан
    4 комментария
  • Как сохранить "лайки" в localStorage?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    localStorage это простое хранилище в вашем браузере.
    Туда можно положить текст setItem(), или вытащить getItem(), если есть — всё тот же текст.

    С «лайками» алгоритм такой:
    1. загружается страница;
    2. смотрим, есть ли сохранённые в LS лайки – если есть показываем их;
    3. при каждом обновлении счётчика лайков, записываем в LS.

    spoiler
    const KEY = 'my-likes';
    let likes = 0; // по умолчанию
    if (localStorage.hasOwnProperty(KEY)) likes = +localStorage.getItem(KEY);
    const showLikes = n => document.querySelector("#root").innerText = n;
    showLikes(likes);
    let plusOne = () => {
      likes++;
      localStorage.setItem(KEY, likes);  
      showLikes(likes);
    }
    Ответ написан
    3 комментария
  • Как более грамотно переписать подобный код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Дублируется логика вычисления урона здоровью от случайного балла, надо её в функцию:
    const hpDelta = chance => 10 + (chance > 5 ? 10 : 0) + (chance > 7 ? 20 : 0);


    spoiler
    const simpleFight = () => {
        let player_hp = 100;
        let enemy_hp = 100;
        let player_chance;
        let enemy_chance;
    
        const hpDelta = chance => 10 + (chance > 5 ? 10 : 0) + (chance > 7 ? 20 : 0);
        const randomChance = () => Math.floor(Math.random() * 11);
        const healthReport = hello => console.log(`${hello||''} Your health: ${player_hp}%, enemy health: ${enemy_hp}%`);
        const chanceReport = hello => console.log(`${hello||''} Your chance: ${player_chance}, enemy chance: ${enemy_chance}`);
    
        healthReport("Welcome!");
    
        while (player_hp || enemy_hp > 0) {
            player_chance = randomChance();
            enemy_chance = randomChance();
            chanceReport();
            if (player_chance > enemy_chance) {
                enemy_hp -= hpDelta(player_chance);
                console.log(`Your turn. Enemy health updated to: ${enemy_hp}%`);
            } else if (enemy_chance > player_chance) {
                player_hp = hpDelta(enemy_chance);
                console.log(`Enemy's turn. Your health updated to: ${player_hp}%`);
            } else {
                chanceReport('Equal chances!');
            }
    
            if (enemy_hp <= 0) {
                healthReport('You win!');
                break;
            } else if (player_hp <= 0) {
                healthReport('You lost!');
                break;
            }
        }
    }
    
    
    simpleFight();
    Ответ написан
    Комментировать
  • Как отловить событие нажатия двух клавиш?

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

    По событию keyup удаляйте из массива нажатых код этой клавиши.


    Во вкладке Result кликните на белом поле и нажмите Shift + Tab
    Ответ написан
    3 комментария
  • Как переписать функцию красивее?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    r.forEach(e => e.field = myFunc(e.field));

    Метод forEach() применит функцию к каждому элементу массива.
    Т.к. задача только поменять свойство внутри каждого объекта, а объекты в 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 и т.п.
    Ответ написан
    Комментировать