Задать вопрос
  • Как отформатировать строку?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Я бы так сделал:
    // export или module.export =
    function formatText(text, formatters) {
      return formatters.reduceRight(applyFormatter, text);
    }
    
    function applyFormatter(text, formatter) {
      const {offset, length, type} = formatter;
      const endOffset = offset + length;
      const wrapper = getWrapper(type);
      return `${text.slice(0, offset)}${wrapper(
        text.slice(offset, endOffset),
        formatter
      )}${text.slice(endOffset)}`;
    }
    
    function getWrapper(type) {
      switch(type) {
      case 'bold':
        return boldWrapper;
      case 'text_link':
        return linkWrapper;
      default:
        return identityWraper;
      }
    }
    
    function boldWrapper(text) {
      return `<b>${text}</b>`;
    }
    function linkWrapper(text, {url}) {
      return `<a href="${url}">${text}</a>`
    }
    function identityWraper(text) {
      return text;
    }

    Использование:
    console.log(formatText('qwerty Ссылка', [
      { offset: 0, length: 7, type: 'bold' },
      { offset: 7, length: 6, type: 'text_link', url: 'https://vk.com/' }
    ])); // <b>qwerty </b><a href="https://vk.com/">Ссылка</a>
    Ответ написан
    Комментировать
  • Как работает оператор +?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    В js оператор + перегружен. Можно представить, что под капотом он вызывает функцию от двух аргументов (левого и правого операнда), примерно такую:
    function add(left, right) {
      const typeLeft = typeof left;
      const typeRight = typeof right;
      if(typeLeft === 'string') {
        return left.concat(right);
      }
      if(typeRight === 'string') {
        return right.concat(left);
      }
      if(canConvertToNumber(left, typeLeft) && canConvertToNumber(right, typeRight)) {
        return Number(left) + Number(right); // тут уже не перегруженный вариант + иначе будет бесконечная рекурсия
      }
      if(typeLeft === 'bigint' && typeRight === 'bigint') {
        return left + right; // опять не перегруженный вариант
      }
      if(
        (typeLeft === 'bigint' && canConvertToNumber(right, typeRight))
        || (typeRight === 'bigint' && canConvertToNumber(left, typeLeft))
      ) {
        // если предыдущий if не прошел, а проходит этот
        // то мы складываем bigint с не bigint, а так нельзя
        throw new TypeError('Cannot mix BigInt and other types, use explicit conversions');
      }
      // во всех остальных случаях приводим к строке:
      return String(left).concat(right);
    }
    
    function canConvertToNumber(item, type) {
      return item === null || type === 'number' || type === 'boolean' || type === 'undefined';
    }
    Ответ написан
    Комментировать
  • Как создать список словарей в c#?

    bingo347
    @bingo347
    Crazy on performance...
    Хм... как то так?
    var saveInfoList = new List<Dictionary<int, SaveInfo>>();
    saveInfoList.Add(new Dictionary<int, SaveInfo>());
    saveInfoList.Add(new Dictionary<int, SaveInfo>());
    saveInfoList.Add(new Dictionary<int, SaveInfo>());
    Ответ написан
    2 комментария
  • Как организовать более правильно скрипты на сайте?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    делаю проект на laravel
    Значит у Вас уже есть laravel-mix, который под капотом использует webpack, а значит можно нормально работать с import

    А потом эти классы импортировать и объекты уже этих классов делать глобальными:
    window.text= new Text();
    window.cart = new Cart();
    window.Form = new Form();

    Что бы потом это не получилось в неуправляемую кашу.
    Как раз такой подход приведет к неуправляемой каше.
    А потом уже в разметке в событиях вызывать методы соответствующих объектов
    Да Вы батенька мазахист...
    Ответ написан
  • Как написать Declaration File в случае если нужно менять свойство объекта?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    // library.d.ts
    type DefaultExport = {
      run(): void;
      check?: (count: number) => void;
    };
    declare const de: DefaultExport;
    export default de;
    Ответ написан
    Комментировать
  • Как сделать объект доступным во всех файлах без импорта?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Можно положить в global, хотя это и не очень хорошая практика
    Ответ написан
  • Почему я могу изменять массив при использовании const?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const делает неизменяемой только ссылку хранящуюся в переменной, на сами объекты оно не влияет
    Ответ написан
    4 комментария
  • JavaScript. Как вытянуть содержимое .css файла?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если стили на нашей странице, то через CSSOM (хорошо гуглится)
    Так же можете поисследовать в консольке document.styleSheets
    Ну и нужно учитывать, что для кроссдоменных стилей нужен CORS
    Ответ написан
  • Зачем передавать самовызываемой функции параметр undefined?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Помимо защиты от подмены, уже описанной в других случаях, аргумент функции будет сокращен до 1 буквы при манглинге кода, что по сравнению с использованием глобального значения позволяет экономить 8 байт бандла на каждое использование undefined
    Аналогично часто делают с window и document
    Ответ написан
  • Итерируемые объекты, почему в цикле первое значение 1?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    В JS есть по 2 оператора инкримента и декримента
    Так
    let x = 10;
    console.log(x++); // 10
    console.log(x--); // 11
    значение сначала будет передано в console.log, а потом посчитано новое
    А так
    let x = 10;
    console.log(++x); // 11
    console.log(--x); // 10
    сначала посчитает, а потом передаст в console.log
    С присваиванием и назначением ключу объекта происходит тоже самое
    Ответ написан
    Комментировать
  • Для чего нужен полиморфизм?

    bingo347
    @bingo347
    Crazy on performance...
    Полиморфизм бывает разный:
    Полиморфизм подтипов - этот тип как раз таки и подразумевают в контексте ООП. Суть в том, что сущность некоторого класса так же может представляться базовым классом или интерфейсом. Это позволяет переиспользовать код, отдавая в один и тот же метод/функцию сущности с разными классами, но с общим интерфейсом.
    Параметрический полиморфизм - используется уже не только в ООП, но и в других парадигмах. Опять таки полиморфная функция принимает аргумент разных типов, при этом сам тип так же передается как параметр функции, а следовательно функция может оперировать составными типами на основе переданного. Или например возвращать результат того же или производного типа, сохраняя тем самым тип для вызывающего кода. Чаще всего представлено дженериками, но могут быть и другие формы (например template в C++). Как правило не имеет смысла в языках с динамической типизацией. А еще часто сопровождается контрактами на получаемый тип (например типами высшего порядка или типажами), что позволяет с одной стороны ограничить возможные типы, а с другой - воспользоваться характеристиками типа обусловленными контрактом.
    ad-hoc полиморфизм - способность функции предоставить разную реализацию в зависимости от запрашиваемой сигнатуры. Чаще всего выражено перегрузкой функций/методов. Как правило не реализуем средствами языка с динамической типизацией, хотя может быть реализован в рантайме (например в js функция всегда принимает произвольное количество аргументов и может проанализировать их в рантайме с помощью arguments).

    В общем случае полиморфизм нужен для переиспользования кода. Соблюдения практик SOLID и DRY не возможно без полиморфизма. Например в языке Go отсутствие полиморфизма в любом виде приводит к загрязнению кодовой базы и большому количеству копипасты.

    И еще, из моего ответа, может сложится мнение, что полиморфизм не применим к языкам с динамической типизацией, например к Python. На самом деле это не так, в ЯП с динамической типизацией полиморфизм наоборот возведен в абсолют.

    UPD: Примеры:
    правда я не шибко хорошо знаю конкретно Python, поэтому абстрактно напишу псевдокод:

    Полиморфизм подтипов, как уже говорил, это про ООП. Допустим у меня задача реализовать класс, который читает бинарные данные, проверяет, что они валидный utf-8 и выдает прочитанное как строку. Откуда он читает их? Да мне все равно, это не относятся к моей задаче. Конкретную реализацию я приму в аргументах, а уж откуда она будет читать, из файла или из сети - мне все равно. Главное чтоб эта реализация умела читать байты.
    // ok мне нужно что-то, что умеет читать байты, опишу это интерфейсом
    interface IByteReader {
      readBytes(): BytesIterator;
    }
    
    // и мой метод:
    readAsString(reader: IByteReader): string {
      var iterator: BytesIterator = reader.readBytes();
      // ну и тут как то с ним работаю, трансформируя байты в строку
    }
    теперь вызывающий код может передать в мой метод инстанс любого класса, реализующего мой интерфейс, и мне теперь не нужно дублировать логику чтения строки для файла и для сети.
    Еще один яркий пример тут - функция len() в Python, которая принимает любой тип реализующий одноименный магический метод.

    Параметрический полиморфизм, это про дженерики. Напишем 2 функции, обе будут принимать на вход массив, одна из них будет возвращать начальный элемент, а другая конечный. Но массивы бывают для элементов разных типов. Без параметрического полиморфизма, нам бы пришлось писать реализацию для каждого нужного типа, но благодаря ему мы можем это сделать в обобщенном виде:
    // T - это параметр типа
    fitst<T>(arr: [T]): Option<T> {
      if(arr.has(0)) return Some(arr[0]);
      else return None;
    }
    
    // давайте предположим, что некоторые виды массивов у нас могут быть бесконечными
    // тогда нам понадобится контракт, что можно передавать массивы только с известным размером
    last<T>(arr: [T]): Option<T>
      where [T]: WithKnownSize
    {
      var length: size = get_length(arr);
      if(length == 0) return None;
      else return arr[length - 1];
    }


    ad-hoc полиморфизм, это про перегрузку функций, пусть мы хотим функцию print которая умеет печатать числа и строки:
    print(value: string) {
      stdout.write(value);
    }
    print(value: int) {
      stdout.write(value.to_string());
    }
    Ответ написан
  • Что входит в JavaScript Basic?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Учить можно стихи. Языки, особенно программирования, учить бесполезно.

    Нужно брать, и что-то делать, что-то реальное. Владение языком, неважно английским или JavaScript, приходит только с практикой.
    Так же не плохо освоить (не выучить, а именно освоить, овладеть) программированием в целом, а так же основами Computer Science, дискретной математики, мат. логики и других смежных дисциплин.
    Ответ написан
    Комментировать
  • Как сократить такой код, Waypoints.js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    var allWaypoints = [];
    $('.any, .odds, .simple, .faq, .doctors, .consultation, .stages, .start, .seven').each(function() {
      var $this = $(this);
      allWaypoints.push($this.waypoint(function(direction) {
        $this.addClass('loader');
      }));
    });
    Ответ написан
    1 комментарий
  • Как выбрать между C# и Java?

    bingo347
    @bingo347
    Crazy on performance...
    Никто за Вас не решит.

    Могу поделиться своим субъективным ИМХО полиглота способного закодить многие вещи примерно на 15 различных ЯП - DX (Developer Experience) лучше у шарпа. Система типов будет понадежнее. Контракты на дженерики сделаны весьма хорошо (если бы я не знал Rust, то может и сказал бы, что отлично). Куча приятного сахара, вродеpublic int Field { get; private set; }или async/await или функциональных фишечек вроде замыканий (хотя в Java вроде тоже завезли уже)

    Но самое важное, шарп позволяет писать в любой из 3х парадигм (процедурщина, ФП, ООП) и успешно их комбинировать, а Java хоть и притворяется ООП языком, адекватно и не сожрав всю память пользователя на ней можно писать только процедурщину, пусть и в ООП обертке.
    Ответ написан
    3 комментария
  • Почему с let работает а с var нет?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    У var область видимости функции, на каждой итерации цикла мы имеем дело с одной и той же переменной.
    У let - область видимости блока, на каждой итерации цикла новая переменная
    Ответ написан
    4 комментария
  • Так ли плохо использовать ORM?

    bingo347
    @bingo347
    Crazy on performance...
    Пока Ваши запросы простые и вписываются в те кейсы, которые реализовали создатели ORM - будут сплошные плюсы: разрабатывать быстрее, данные сразу отображаются в доменную область, производительность почти не страдает.
    Но в реальном мире такие задачи встречаются редко, чаще запросы выглядят как "собери данные по кусочкам с половины всех таблиц в базе, чето посчитай, с агрегируй и выдай вот в таком виде". Если ORM и позволяет такое делать, то делает как правило не самым оптимальным образом. И не редко в таких случаях приходится еще и бороться с очень умной ORM...
    Как альтернативу ORM я бы еще посмотрел в сторону конструкторов запросов, где монотонные штуки хорошо абстрагированы, но в случае чего можно кусок написать на чистом SQL. И на выходе не сайд эффект в виде запроса к базу, а строка со SQL, которую можно уже отправить в базу, или сохранить в файлик, или вставить в другой запрос.
    Ответ написан
    2 комментария
  • Как воспользоваться скрытой от удаленного репозитория локальной веткой?

    bingo347
    @bingo347
    Crazy on performance...
    Помимо Fast Forward Merge можно делать cherry-pick комитов по одному и создавать иллюзию, что Вы активно работаете здесь и сейчас
    Ответ написан
    Комментировать
  • Возможно ли сделать promisify для дочернего процесса spawn?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    promisify меняет сигнатуру функции с условного
    function func<T>(...args: any[], cb: (err: any, result: T) => void): any;
    // или
    function func<T1, T2>(...args: any[], cb: (err: any, res1: T1, res2: T2) => void): any;
    на
    function func<T>(...args: any[]): Promise<T>;
    // или
    function func<T1, T2>(...args: any[]): Promise<{res1: T1; res2: T2}>;

    Для exec это возможно, так как его сигнатура подходит под 2 вариант:
    function exec(command: string, options?: ExecOptions, cb: (err: Error, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess;
    что приходит к сигнатуре:
    function exec(command: string, options?: ExecOptions): Promise<{stdout: string | Buffer; stderr: string | Buffer}>;

    Для spawn этого сделать нельзя, ибо сигнатура не подходит:
    function spawn(command: string, args: string[], options: SpawnOptions): ChildProcess;
    Просто некуда подставить колбэк, который будет отслеживать промис
    Ответ написан
    Комментировать
  • Как доабвить import в webpack конфиге?

    bingo347
    @bingo347
    Crazy on performance...
    const Webpack = require('webpack');
    Ответ написан
    Комментировать