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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    «250 строк кода, распознающих дату на русском языке»

    Из тяжелой артиллерии можно посмотреть Яндекс Томита парсер есть в обёртках под nodejs. Хотя он вроде, под даты не заточен.
    Ответ написан
    Комментировать
  • Лучше больше кода, но лёгкого или меньше, но сложного?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    При каждом изменении поля (событие "input") выкидывать всё, кроме цифр (и знаков подчёркивания?), и форматировать в шаблон.
    Ответ написан
    Комментировать
  • Как убрать влияние часового пояса?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Внутри, объект Date не хранит указание на временную зону, он считает время всегда в UTC и значением хранит только число миллисекунд с 1970-01-01 00:00:00 UTC. Он также в курсе временной зоны устройства, и может учитывать её при формировании вывода.

    Когда в конструктор Date передаётся только 1 аргумент (ваш случай), этот аргумент интерпретируется как время в зоне UTC; когда больше одного – в местной временной зоне.

    Как я понял, вы хотите создать объект Date, передав дату-время в UTC?

    Попробуйте так:
    function toDate(date, time) {
        return new Date( Date.UTC( date + ' ' + time));
    }


    Формат dd/mm/YYYY HH:mm можно получить, составляя из компонент. Опять же, по UTC получить, или в локальной временной зоне? Для UTC будет выглядеть так:
    function pad(n){ return ('0' + n).substr(-2) }
    function toUTCString(d) {
      return '' + pad( d.getUTCDate()) + '/' + pad(d.getUTCMonth()+1) + '/' + d.getUTCFullYear()
        +' ' + pad( d.getUTCHours()) + ':" + pad( d.getUTCMinutes());
    }


    В локальной временной зоне устройства – уберите 'UTC' из всех методов )
    Ответ написан
  • Как делают автоответчики на javascript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Посмотрите на wit.ai
    Ответ написан
    Комментировать
  • Как добавить в регулярное выражение флаги?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Предположение: под «массивом регулярок» вы имеете в виду просто массив слов, с одним из которых ищется совпадение. Тогда можно так:
    var r = ['купить','дешево','по ссылке'];
    var msg = "хотите купить гараж?";
    var re = new RegExp( r.join("|"), "gim"); // одно ИЛИ другое ИЛИ третье
    if( re.test( msg)) { // спам detected }
    Ответ написан
    Комментировать
  • Как остановить выполнение функции или цикла по истечению времени?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно, например, какой-то флаг поднимать, когда пора функции прекратить работу. А внутри функции, по возможности, смотреть, не поднят ли флаг, и если да – выходить.
    var flag = false; // когда будет true - тушите свет!
    function game() {
      var i;
      while(true) { // на самом деле из цикла так не выйти
           // пока он крутится, другие потоки не смогут запуститься и изменить значение флага
        i = i++;
        if(flag) return; // выход, когда пора
      }
    }
    setTimeout( function(){ flag = true;}, 60000}); // через минуту поднять флаг
    game();


    Другой вариант, более подходящий для цикла - заранее назначить время выхода и смотреть на часы:
    var timeToExit = (new Date).getTime() + 300000; // через 5 минут
    function game() {
      var i;
      while(true) {
        i = i++;
        if( (new Date).getTime() >= timeToExit) return; // выход, когда пора
      }
    }
    game();
    Ответ написан
    2 комментария
  • Как зашифровать строку методом "Железнодорожной изгороди"?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Для начала отдельное упражнение – как из индекса буквы в исходной строке получить индекс строки, в которую его положить.

    Обозначу число строк переменной rows. Период этой «пилы» от верхнего пика до следующего верхнего пика составляет 2 * (rows - 1). Остаток от деления на этот период будет означать позицию внутри одного «зуба»:
    остаток: 0 1 2 3 4 5
     строка: 0 1 2 3 2 1 – это хочется в итоге как-то получать


    Чтобы просчитать «отражение» – когда шли вниз и потом стали идти вверх – надо подогнать этот момент и сделать пересечением оси y = 0 и тогда отражение легко сделать, взяв абсолютное значение Math.abs():
    y  : 3  2  1  0 -1 -2
    abs: 3  2  1  0  1  2


    Остаток от деления будет всегда положительным и растущим: 0 1 2 3 4 5, а нужно получить из него 3 2 1 0 -1 -2. Умножить на -1 и добавить 3: Math.abs(rows - 1 - ost)

    Итого примерно такой код даст правильные номера строк, куда вставлять символ, получая на вход i – индекс буквы в исходной строке:
    var i, ost, row, rows=4, period = 2 * (rows - 1); //   0 0 0   |    6 0 0
    for(i = 0; i < 10; i++) {                         //   1 1 1   |    7 1 1
      ost = i % period;                               //   2 2 2   |    8 2 2
      row = rows - 1 - Math.abs(rows - 1 - ost);      //   3 3 3   |    9 3 3
      console.log( i, ost, row);                      //   4 4 2   |   10 4 2
    }                                                 //   5 5 1   |   11 5 1


    В сборе будет выглядеть примерно так:
    function encrypt( text, n) {
      var i, ost, period = 2 * (n-1), r, row, out = [];
      text = text.replace(/\s/g,""); // убрать пробелы
      for(r = 0; r < period; r++) out[r] = ""; // пустые строки
      for(i = 0; i<text.length; i++) {
        ost = i % period;
        row = n - 1 - Math.abs(n - 1 - ost)
        out[row] += text.substr(i,1);
      }
      return out.join("");
    }
    
    function test( text, rows) {
    	var pre = document.createElement("pre");
    	pre.innerHTML = encrypt(text, rows);
    	document.body.appendChild(pre);
    }
    
    test("этот текст зашифрован", 4); // экинтесшфаоттарвтзо

    jsFiddle

    Upd. чуть переписал это дело. Шифровка и расшифровка осуществляются на основе одной и той же «карты», которая зависит только от числа букв в тексте и числа строк. Поэтому сделал одну ф-ю, создающую эту карту. И слегка отличающиеся короткие функции шифровки и дешифровки. Фиддл с формой. Код шифровки/дешифровки такой:
    function makeMap( len, n) {
      var i, pip, period = 2 * ( n - 1);
      var rows = Array.apply( null, Array( n)).map( function(){ return []});
      for( i = 0; i < len; i++) {
        pip = i % period;
        r = pip < ( n - 1) ? pip : period - pip; 
        rows[ r].push( i);
      }
      return Array.concat.apply( null, rows);
    }
    
    function decrypt( text, n) {
      var map = makeMap( text.length, n);
      return text.split('').reduce(function(p,c,i,a){ return p + a[map.indexOf(i)]},'');
    }
    
    function encrypt( text, n) {
      var map = makeMap( text.length, n);
      return text.split('').reduce(function(p,c,i,a){ return p + a[map[i]]},'');
    }
    Ответ написан
    4 комментария
  • Что делают значения в функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Прочитайте, пожалуйста, https://learn.javascript.ru/function-basics – обратите внимание на «локальные переменные».

    Попробую разложить по полочкам.

    var a = 1, b = 2; // эти a, b – «глобальные», выше всех, «видны» везде
    function calculate(x, y, z) {
      // здесь определены локальные переменные x, y, z
      // и видны все переменные из уровней выше
      // напр. a и b
      // ждём, что x – это будет функция
      return x( y+a, z+b); // можно использовать и локальные и глобальные
    }
    
    function sum( a, b){ // а вот тут a,b – переопределены локально
      // и к тем, глобальным a и b не имеют никакого отношения!
      return a+b; // складывает те a и b, что передали при очередном вызове sum()
    }
    
    calculate( sum, 5, 6); // вызывает calculate, и там будет x = sum, y=5, z=6
    sum( 7, 8);  // вызывает напрямую sum, внутри которого будет a=7 и b=8
    // при этом глобальные a и b никак не пострадают.
    Ответ написан
    Комментировать
  • Как сделать простановку пробелов с конца в моей регулярке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Регуляркой:
    var n = 12345678;
    n = n.toString(10).replace(/(\d)(?=(\d{3})+$)/g, '$1 '); // 12 345 678


    Можно и без регулярок. Строку разбить в массив, развернуть, к каждому третьему символу приделать пробел (идём с конца, получается), собрать в строку:

    var n = 123456789;
    
    var a = n
      .toString(10)
      .split('').reverse()
      .map(function(e,i){ return (i%3 ? e : ""+e+" ")})
      .reverse()
      .join('')
      .trim()
    ;
    // a = "123 456 789"


    Disclaimer: некорректно может обработать знак минус!
    Ответ написан
    2 комментария
  • Как в середине функции узнать какой метод был вызван?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Предположу, что в примере вызова у вас опечатка, и вы хотели вызывать test.on() – со скобками.

    Обернуть в Proxy, но это не будет работать в старых браузерах и IE и вообще сомнительно, что именно это вам требуется. Может, пересмотреть весь код?
    var test=function(){  
      console.log("method:", arguments[0]);
    };
    
    var handler = {
      get: function( target, name) {
        var _method;
        if(name in target) {
          return target[name];
        } else {
          return target.bind( null, name); // если не определено свойство, передаем его 1-м аргументом
        }
      }
    };
    
    test = new Proxy( test, handler);
    
    test.on(); // method: on
    test.blabla(); // method: blabla
    test(); // method: undefined
    Ответ написан
    Комментировать
  • Как делается текст из частиц (particles)?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно такой текст отрисовать в SVG и дать атрибут stroke-dasharray, чтобы по периметру букв получился пунктир точками. Размножить слой и разнести по оси Z, чтобы получился небольшой объём.

    Более экспериментальный вариант, плохо поддерживаемый браузерами, CSS3 свойство text-stroke (-webkit-text-stroke). Смысл тот же – сделать обводку букв пунктиром и наделать копий слоя со смещением по Z.

    И, наконец, можно всё это отрисовать в canvas.
    Ответ написан
    Комментировать
  • Почему цикл не повторяется?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В вашем коде цикл while не содержит в «теле» ничего – после скобок сразу закрывается точка-с-запятой.

    Вот так вы, наверное, имели в виду:
    var answer;
    do {
      answer = prompt("Скажи 'стоп'", "");
      document.write("Ты сказал '" + answer + "'.");
    } while (answer !== "стоп");


    Есть два варианта while-цикла:
    1. while( условие) { действия }
    2. do{ действия } while( условие )
    В этой задаче точно нужен второй: сначала надо выполнить действия (попросить сказать «стоп»), а потом уже проверить условие (что ввел пользователь?).
    Ответ написан
    3 комментария
  • Как имитировать двойной клик?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Дабл-клик делается так: создать событие и отправить его через dispatchEvent():
    var event = new MouseEvent('dblclick', {
        'view': window,
        'bubbles': true,
        'cancelable': true
      });
    document.getElementById('button').dispatchEvent(event);

    Полагаю, в вопросе опечатка и вы имели в виду «имеется id #button».
    Ответ написан
    Комментировать
  • Как работать с методом groups.getMembers вконтакте с помощью JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Посмотрите мой открытый проект по сбору списка всех Участников сообщества. Только JavaScript. Демо.

    Реализация с web worker'ом и учётом времени выполнения запросов, чтобы не вылезти за лимит трёх запросов в секунду.
    Ответ написан
    Комментировать
  • Как настроить функцию для передачи различных значений?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Внутри возвращаемой функции запоминайте значение:
    function nds( cost) {
      return function() {
        var _cost = cost;
        var result = _cost * 1.13;
        console.log( result.toFixed(2));
      }
    }


    Так возвращаемый экземпляр функции будет содержать в себе переданное значение.

    var a = nds(53);
    var b = nds(12);
    a(); // 59.89
    b(); // 13.56


    Upd. для общего счётчика придётся завести переменную, видимую из всех функций:
    var total = 0;
    
    function nds( cost) {
      return function() {
        var _cost = cost; // запомнили внутри цену
        var result = _cost * 1.13; // добавили НДС
        total += result; // добавили к общей сумме
        console.log( "result:", result.toFixed(2), "total:", total.toFixed(2));
      }
    }
    
    var a = nds(53);
    var b = nds(12);
    
    a(); // result: 59.89 total: 59.89
    b(); // result: 13.56 total: 73.45
    a(); // result: 59.89 total: 133.34
    a(); // result: 59.89 total: 193.23
    Ответ написан
    2 комментария
  • Зачем в данном примере this, если с именем обьекта тоже работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В вашем примере разницы нет и this удобнее только тем, что при переименовании "arr" не придётся ещё две замены делать.

    Хотя, если дальше вы используете наследование, то разница принципиальна. Например, создать новый объект, используя arr как прототип:
    var arr = {
      "name" : "Stive",
      "age" : 29,
      "all" : function() { return this.name + " " + this.age; }
    };
    var b = Object.create(arr);
    b.name = "Bill";
    b.age = 39;
    b.all();

    С this в arr код для b выполнится нормально и вернёт "Bill 39", а если в arr вместо this было прямое указание на arr, то вернёт "Stive 29".
    Ответ написан
    Комментировать
  • Почему неправильно работают операторы с 64 битным числом?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Самое большое целое в JS: (253 - 1)

    Минимальное целое: (-(253 - 1))

    (источник)

    Операнды всех битовых операций конвертируются в 32-х битовые целые со знаком представленные в дополнительном коде и с использованием порядка битов от "старшего к младшему".

    Битовые операции с 64-битными – никак. Бейте на два 32-битных.
    Ответ написан
  • Суть 3 строки,если можно подробно "по символам грубо говоря"?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    ! ! ~ s.indexOf( substring) – такая короткая запись означает «есть ли подстрока?»

    Как это работает. Метод объекта строки indexOf() возвращает найденное положение подстроки в строке: число от 0 и больше; или –1, когда подстрока не найдена. На деле часто требуется из этого получить true или false – когда интересует лишь, есть подстрока или нет, а позиция её безразлична. Из –1 нам надо получить false, а из всего остального true.

    Для этого используются побитовое НЕ ~ и логическое НЕ !

    ~ обладает замечательным свойством: только из –1 получается 0 (а из нуля –1): ~(-1) === 0

    ! является логическим оператором и его результат – true или false. Например, !5 === false, а !0 === true.

    Это почти то, что нужно, с точностью до наоборот – в случае 0 нужен false, а не-нуля true. Поэтому добавляем ещё одно логическое НЕ. Вот и получается !!~:
    !!~5 === true;
    !!~0 === true;
    !!~-1 === false;


    В вашем примере не один indexOf(), а в скобках перечислены несколько вариантов: (~s.indexOf('AAA') || ~s.indexOf('BBB')).

    || – это логическое ИЛИ. Проверяется слева направо, пока не найдётся первое выражение, которое конвертируется в true, и возвращается его значение как есть, без конвертации в true/false. Например:
    ( false || 5) === 5;
    ( 0 || 0 || 1 || 0) === 1;
    ( 5 || 1 || true) === 5;
    ( false || 0) === 0;


    Значит, несколько ~s.indexOf(substr) будут проверяться до тех пор, пока какой-то не вернёт не-нулевое значение.
    Ответ написан
    Комментировать
  • Что такое выражение, литерал и инициализация в JavaScript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    По-простому я бы объяснил так:
    • выражение – это любой кусок кода, который в итоге даёт значение. Напр. цифра 0 или a===b
    • литерал – это буквально записанное значение. Напр. 10 или "строка" или объект {a:10, b:20}
    • инициализация – придание начального значения. Напр. переменной при создании: var a = 10
    Ответ написан
    3 комментария