Задать вопрос
  • Какие на самом деле типы данных в 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 комментария
  • Как в VUE получить элемент на котором произошло событие?

    bingo347
    @bingo347
    Crazy on performance...
    https://developer.mozilla.org/ru/docs/Web/API/Even...

    $event в Vue как раз прокидывает нативный объект события
    Ответ написан
    Комментировать
  • Как реализуется вывод сообщения об отсутствии соединения?

    bingo347
    @bingo347
    Crazy on performance...
    Помимо событий указанных Алексей Ярков есть еще navigator.onLine
    Ответ написан
    Комментировать
  • Как при нажатии на 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 пальца движутся в противоположных долях - это зум, навстречу друг другу - уменьшение, а от друг-друга - увеличение.
    Ответ написан
    Комментировать
  • Как развиваться если ты один?

    bingo347
    @bingo347
    Crazy on performance...
    мой уровень - middle

    я буду единственным фронтом на проекте

    писать предстоит с нуля

    Ой не завидую я тому, кто будет это проект поддерживать через несколько месяцев...

    Когда Вы один, нет возможности ни посмотреть как схожие задачи решают другие, ни понять, что сам делаешь что-то не то, и это на любом уровне так. Возможно сможете проанализировать свои ошибки постфактум, когда проект загнется, а он обязательно загнется, ибо бизнес на нем экономит не успев начать...
    Заплатят тоже вряд ли нормально, так что смысла идти на такой проект не вижу совсем.
    А сможете ли Вы при этом вырасти - зависит только от Вас. Senior - это больше про ответственность, про проектирование и про глобальное видение проекта целиком. Это сильно отличается от простого делания тасок самостоятельно (middle) или с помощью коллег (junior).
    Что бы писать проект с нуля, его придется проектировать, так или иначе, а это задача senior, если справитись - опыт будет очень полезным. Но скорее всего наделаете ошибок, это нормально для Вас, но плохо для бизнеса, хотя такой бизнес получит именно то, что должен получить нанимая мидла на решение сеньорских проблем...
    Ответ написан
    3 комментария
  • Как получить несколько файлов на сервер?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    По тому что это не JSON, это multipart/form-data, который Вы не обрабатываете
    Ответ написан
  • Как использовать общие типы для нескольких приложений объединенных в проект?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Если Вы предполагаете, что нечто является единой сущностью, то должен быть ровно 1 источник истины, определяющий эту сущность. Типы - это источник истины о структуре Ваших сущностей. Если в двух приложениях Вы оперируете одними и теми же сущностями, то и типы для них должны быть едины, иначе это будет нарушением DRY. Но если по факту сущности разные, то даже если они выглядят одинаково, их нельзя объединить, иначе это будет нарушением SRP.

    Что можно сделать если типы описывают единые сущности:
    1. Если оба приложения живут в одном репозитории, то можно просто переиспользовать одни и те же модули в обоих приложениях. Можно даже сложить их в общую папку и прописать на нее алиас в tsconfig.json и в конфиге сборки.
    2. Если приложение живут в разных репозиториях, то общий код можно вынести в третий репозиторий и подключить его через git модули
    3. А если общий код еще и меняется редко, то разбить его на отдельные npm пакеты - хорошая идея. При этом не обязательно заливать его в публичный репозиторий или покупать у npm приватный, и даже свое зеркало ставить не обязательно (хотя и удобно). Можно просто запаковать пакет в .tgz командой npm pack, а потом устанавливать его из этого .tgz через npm i прямо с файловой системы или с любого http сервера. Кроме того npm i можно делать прямо из git репозитория в корне которого лежит package.json, но как по мне - это не очень хорошая затея, так как в git лежат исходники, а в npm пакете должен быть готовый к использованию (собранный) js код.
    4. Ну и наконец, единый репозиторий так же можно организовать в несколько пакетов, используя npm workspaces и lerna.

    UPD:
    Надо ознакамливаться на что ссылаешься...
    В русской википедии в статье про SRP понаписано много бреда, которого нет в английской версии.
    Забавно, что подобно английской статье, в русской так же ссылаются на Роберта Мартина, который определяет данный принцип правильно (по крайней мере в тех его книгах, что я читал).
    Это очень распространенное заблуждение (OMG, я кажется нашел, откуда все эти люди, что приходят на собеседования, понабрались этого бреда...)
    Принцип единственной ответственности не про то, что код делает что-то одно или отвечает за что-то одно (какая вообще может быть ответственность у текста?).
    Принцип единственной ответственности про то, что у каждой программной сущности есть ровно одно ответственное лицо, и только это лицо является источником изменений в коде этой сущности.
    Ответ написан
    Комментировать
  • Как работать с IndexedDB из класса?

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

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    https://reactjs.org/docs/hooks-reference.html#useref
    const interval = useRef(null);
    
    // ...
    interval.current = setInterval(//...
    Ответ написан
    Комментировать
  • 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]);
    Ответ написан
  • Как написать одну функцию для 4 разных компонентов?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    // хелперы
    const makeCustomTextFieldWithState = (): [string, ReactElement] => {
      const [value, setValue] = useState<string>('');
      const onChange = (event: React.ChangeEvent<HTMLInputElement>) =>
        setValue(event.target.value);
      return [value, <CustomTextField onChange={onChange} />];
    };
    
    const makeManyCustomTextFieldWithState = (count: number): [string[], ReactElement[]] =>
      Array(count).fill(0).reduce(([values, elements]) => {
        const [value, element] = makeCustomTextFieldWithState();
        return [
          [...values, value],
          [...elements, element],
        ];
      }, [[], []]);
    
    // в компоненте
    const [[dept, login, firstName, lastName], elements] = makeManyCustomTextFieldWithState(4);
    <>{elements}</>
    Ответ написан
    Комментировать
  • С чего начать изучение языка?

    bingo347
    @bingo347
    Crazy on performance...
    Вы нигде и никогда не найдете руководства по переходу с языка А на язык Б. Бэкграунд у всех разный и такие руководства просто не имеют смысла.

    А еще ответьте себе на вопрос, зачем Вам Rust? В JS/TS нет и половины тех проблем, которые он решает. Да, ценой некоторых ресурсов, но нет.
    А еще, есть два типа людей - те, которые думают, что в TypeScript/Java/C# сильная система типов, и те, кто понимает, что они в разы слабее чем в ML языках. Система типов Rust - это доработанная система типов OCaml со всеми вытекающими. Тут кстати можно в мире JS попробовать ReasonML/ReScript и сравнить с TypeScript, чтоб понять суть было проще.

    А общий рецепт освоения Rust выглядит так:
    1. Прочитать Rustbook на русском, но лучше на английском.
    2. Посмотреть лекции Алексея Кладова
    3. Rust by example на русском или на английском
    Ну и конечно никуда без практики

    И да, всю прелесть borrow checker понять не получится, пока не по управляете памятью руками. Но для этого не обязательно лезть в C/C++, можно на том же Rust, правда придется окунутся в unsafe, так что отложите это на попозже, а сейчас воспримите borrow checker, как часть строгой системы типов, которая всеми силами пытается Вам помочь.
    Ответ написан
  • Чем JavaScript абстрактнее других языков программирования?

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

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

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

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

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

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

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Inplace не получится, но можно в новую:
    const sortedMap = new Map([...map.entries()].sort(([, a], [, b]) => b - a));
    console.log(sortedMap);


    Хотя если сильно хочется, то можно и inplace наколдовать, через очистку и перезапись:
    const sorted = [...map.entries()].sort(([, a], [, b]) => b - a);
    map.clear();
    sorted.forEach(([k, v]) => map.set(k, v));
    console.log(map);
    Ответ написан
    Комментировать
  • Как правильно присвоить класс?

    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 комментария