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

    search
    @search
    мама говорит что я особенный
    Вообще, многие задачи можно свести к правильному выбору структуры данных. Да-да, есть всякие задачи поиска кратчайшего пути, жадные алгоритмы, динамическое программирование. Но в основном, те задачи, которые появляются на сайтах, подобных codewars или на собеседованиях, можно так или иначе решить, выбрав правильную структуру данных.

    Советую методично прорешать все задачи из этого раздела хакерранка https://www.hackerrank.com/domains/data-structures . В прошлом это повысило мой скилл и дало немало уверенности в себе. Удачи!
    Ответ написан
    Комментировать
  • Почему Webstorm подсвечивает оператор spread?

    search
    @search
    мама говорит что я особенный
    Попробуйте внизу экрана нажать кнопку Typescript и найти там пункт Restart. Обычно помогает в таких ситуациях.
    Ответ написан
  • Какую альтернативу Prettier можно посоветовать, чтобы решить проблему длинных и коротких строк?

    search
    @search
    мама говорит что я особенный
    Вот тут обсуждают как это преодалеть, но методы черезжопные: https://github.com/prettier/prettier-vscode/issues/352

    Единственная альтернатива преттиеру - это eslint, но это так себе альтернатива, если честно.

    На вашем месте я бы внедрил преттиер и доверился ему. Его используют проекты на тысячи контрибьютеров (тот же реакт и ангулар) и особо не жалуются. Да, в нём есть недостатки, и не всем нравится формат. Но единообразный формат кода и отсутсвие споров на тему что лучше, перевешивают любые его минусы. Не использовать преттиер потому что он сворачивает короткие массивы и в гит блейме сразу не видно кто добавил элемент в массив - это как не пользоваться ножом потому что можно порезаться.
    Ответ написан
    4 комментария
  • Примеры unit тестов реального приложения на express\koa?

    search
    @search
    мама говорит что я особенный
    Сейчас прозвучит мысль, к которой многие программисты не готовы: юнит тесты - это пустая трата времени*.

    * бывают исключения, о них ниже.

    Вы сами заметили что в основном тесты получаются сложнее чем код. Мок погоняет моком. А возня с тестами занимает больше времени чем работа над бизнес кодом. Это стандартная болезнь многих проектов. Причина этой болезни - вера в то что тесты каким-то чудесным образом способствуют качеству приложения. Это не так. В некоторых случаях тесты помогают быстрее писать код и быстрее его понимать. В основном это касается:
    - чистых функций (типа пресловутого sum) и функций общего назначения (например из lodash)
    - регулярных выражений

    Юнит тесты не имеют смысла на так называем "клее". Например коде контроллера, который, в теории должен быть простым как топор. Обычно клей - это код, который связывает какие-то логические узлы, при этом сам имея тривиальную логику. Это где-то 90% кода современных приложений. Тестировать клей - так же нелепо, как и тестировать сам фреймворк или node. Тесты в стиле "сейчас мы убедимся что этот сервис вызвает другой сервис, передавая в него такие-то прараметры" обходятся крайне дорого, а на выходе не дают никакой практической ценности. Потому что тест получается сложнее чем сам клей, что противоречит постулатам TDD.

    Но всё-таки хочется обладать определённой степенью уверенности в том что делаешь. Для этого есть:

    - тайпксприпт (ну или другой строго типизированный язык). Со строгой типизацией не нужно волноваться о том что где-то в недрах клея мы забыли передать параметр или забыли его как-то сконвертировать в другой тип. В общем всё что касается "а вдруг кто-то случайно забыл" решается строгой типизацией
    - функциональные тесты. Но тут тоже нужно быть осторожным. Например тестирование того что у вас "правильный" HTML на выходе - это так же глупо как юнит тестировать сам фреймворк.

    Такие дела.
    Ответ написан
    6 комментариев
  • Как добавить в аргумент функции обработчика значение инпута?

    search
    @search
    мама говорит что я особенный
    Вот так

    //...
    getChangeBonusTypeHandler = (event) => this.getChangeBonusType(event.target.value);
    //...
    render() {
      return <input onChange={this.getChangeBonusTypeHandler}/>
    }
    Ответ написан
  • Можно ли задать плавное появление директиве ngSwitch?

    search
    @search
    мама говорит что я особенный
    Да, это можно сделать при помощи ангуляровской системы анимации.

    Вот пример того как анимация реализована для ngFor https://stackblitz.com/edit/ng-animations?file=ani...
    Принцип не отличается от ngSwitch.

    Здесь можно почитать подробнее https://angular.io/guide/transition-and-triggers
    Ответ написан
    Комментировать
  • Почему ругается на catch?

    search
    @search
    мама говорит что я особенный
    Сделаейте

    .catch(err => reject(err))

    а не

    .catch(err = reject(err))

    и перестанет ругаться.
    Ответ написан
    Комментировать
  • Рекурсия в JavaScript?

    search
    @search
    мама говорит что я особенный
    Это не нормальное решение прежде всего потому что функции знают о:
    1. существовании друг друга
    2. существовании некоего правила последовательности их вызова

    Такой код называется высокосвязным. Высокосвязный код дорого поддерживать потому что приходится учитывать множество деталей его реализации. Учебники рекомендуют создавать как можно более обособленные функци: так называемые "чистые функции".

    Сделать функции чище можно, например, так:

    const delay = timeout =>
        Promise(resolve => setTimeout(() => resolve(), timeout));
    
    async function delayedQueue() {
        first();
        await delay(1000);
        second();
        await delay(1000);
        third();
    }
    
    delayedQueue();


    Как видите, теперь функции, которые необходимо вызвать с задержкой, не подозревают о существовании друг друга, а само правило последовательности их вызова инкапсулировано в отдельной функции delayedQueue.
    Ответ написан
    Комментировать
  • Блок не содержит класс, как написать проверку?

    search
    @search
    мама говорит что я особенный
    Я бы на вашем месте делал это без ифа, потому что внутри ифа сложно будет сказать к какому именно блоку относится `.thumbnail-container-images`.

    Можно сделать так:

    $(".thumbnail-container:not(.with_thumb) .thumbnail-container-images").css("width","77%")


    Что означает: присвоить всем .thumbnail-container-images, которые находятся внутри .thumbnail-container:not(.with_thumb) ширину 77%.
    Ответ написан
  • Как отобразить определенное кол-во элементов массива и переключаться между ними на клик?

    search
    @search
    мама говорит что я особенный
    Идея такая:

    const [page, setPage] = useState(1);
    const itemsPerPage = 8;
    ...
    {orgs.slice((page - 1) * itemsPerPage, page * itemsPerPage).map(...)}
    ...
    <button onClick={() => setPage(page + 1)}>Next</button>
    <button onClick={() => setPage(page - 1)}>Previous</button>


    Конечно, нужно предусмотреть чтоб по нажатию на кнопки Next и Previous мы не уезжали за пределы мыссива.
    Ответ написан
    1 комментарий
  • Как удалить ключ в обьекте из LocalStorage?

    search
    @search
    мама говорит что я особенный
    К сожалению, удаление ключа из объекта при помощи деструктурирования выглядет как ужасное уродство как ни старайся. Советую создать вспомогательную функцию `omit(keys, object)` наподобии омита из библиотеки lodash или ramda. https://github.com/ramda/ramda/blob/master/source/...
    Ответ написан
    1 комментарий
  • Как заполнить state?

    search
    @search
    мама говорит что я особенный
    Не совсем понял проблему, но стены находятся в первом элементе массива action. Если вы хотите передать их в state, то это можно сделать как-то так

    game$.subscribe((action) => {
      switch (action[0]) {
        case 'ArrowUp':
          if(state.y > 0) { state.y--; }
          break;
        case 'ArrowRight':
          if(state.x < gameWidth - 1) { state.x++; }
          break;
        case 'ArrowDown':
          if(state.y < gameHeight - 1) { state.y++; }
          break;
        case 'ArrowLeft':
          if(state.x > 0) { state.x--; }
          break;    
      }
      
      state.walls = action[1];  
      renderGame(state);
      console.log(state)
    });
    Ответ написан
    Комментировать
  • Как обойти граф и найти его вершину?

    search
    @search
    мама говорит что я особенный
    Погуглиите DFS или BFS. И тот и тот алгоритм вам подойдёт. DFS рекурсивный (можно свести к нерекурсивному), а BFS нерекурсивный. Чтоб проще было понять в чём дело, можно найти видео на ютубе. Просмотр займёт минут 5-10.
    Ответ написан
    Комментировать
  • Как связать компоненты между страницами?

    search
    @search
    мама говорит что я особенный
    Вынесите объявление сервиса в `providers` главного модуля. И уберите объявление сервиса из `providers` других модулей.

    Каждый раз когда вы добавляете сервис в `providers` модуля, анугяр создаёт экземпляр сервиса именно для этого модуля. И в другом модуле этот экземпляр виден не будет.
    Ответ написан
    Комментировать
  • Как работает (arg)=>(arg)=> и т.д?

    search
    @search
    мама говорит что я особенный
    Это называется "стрелочная функция" https://developer.mozilla.org/ru/docs/Web/JavaScri...

    (arg) => arg

    это то же самое что и

    function (arg) {
      return arg;
    }


    а

    arg => arg => arg;

    это то же самое что

    function(arg) {
      return function(arg) {
        return arg;
      }
    }


    Последний пример не имеет особого смысла потому что первый arg никак не учитывается в дальнейшем.

    У стрелочных функций есть одна особенность, отличающая их от обычных функций: стрелочная функция получает тот контекст this, где она была объявлена. За это их все безумно любят и предпочитают использовать вместо обычной function.
    Ответ написан
    1 комментарий
  • Количество цифр в зависимости от совпадения маски?

    search
    @search
    мама говорит что я особенный
    ^(?:7\d{10}|421\d{9})$

    https://regex101.com/r/FTME89/1
    Ответ написан
    Комментировать
  • Для чего в react используют регулярно метод bind?

    search
    @search
    мама говорит что я особенный
    Люди древности так привязывали метод к контексту. В давние времена не существовало стрелочных функций.

    В вашем примере мы передаём функцию this.addFriend в обработчик события addNew. JS так устроен что когда вы передаёте this.addFriend (куда угодно, хоть в обработчик, хоть в переменную), то будет передан только addFriend без this. Bind как раз нужен для того чтоб прибить FriendsContainer к контексту метода addFriend.

    В современном мире принято делать так:

    class FriendsContainer extends React.Component {
      addFriend = (friend) = >{
        this.setState((state) => ({
          friends: state.friends.concat([friend])
        }))
      }
    }


    Это по сути тот же bind, только без лишних телодвижений.
    Ответ написан
    Комментировать
  • Не могу пройти задание на FCC?

    search
    @search
    мама говорит что я особенный
    Ваш код возвращает массив строк типа "Inception:8.8".

    А в задании хотят чтоб он возвращал массив объектов типа {title: 'Inception', rating: '8.8}.

    Нужно как-то так:

    rating = watchList.map(({ "Title": title, "imdbRating": rating }) => ({title, rating}));
    Ответ написан
    4 комментария
  • Rxjs - как сделать двойной subscribe?

    search
    @search
    мама говорит что я особенный
    Обзёрвер не выполняет никакой работы до тех пор пока не была вызвана функция subscribe. Сам процесс вызова subscribe называется "подписка". Как только функция subscribe была вызвана (т.е. на обзёрвер подписались) - дело пошло и обзёрвер начал свою работу. До тех пор пока subscribe не вызван, обзёрвер - это просто рецепт того что нужно делать когда прийдут данные.

    Сама функция subscribe возвращает деструктор. Деструктор - это что-то что нужно выполнить, если вдруг понадобилось остановить обсёрвер (например прервать HttpConnection).

    Код ниже возвращает функцию-деструктор

    let get = () => {
        return this.http.get(url)
            .subscribe((response: ResponseObject) => {...});
    }


    На функцию-деструктор невозможно подписаться. Коллбеков у неё тоже нет. Её можно только выполнить для того чтоб остановить обзёрвер.

    Поэтому, универсальный рецепт - это никогда не подписываться в самих сервисах. Если вам нужно что-то проделать с данными из обзёрвера в самом сервисе, то можно воcпользоваться оператором tap:

    let get = () => {
        return this.http.get(url)
            .pipe(
              tap((response: ResponseObject) => {...})
            );
    }
    
    // а дальше где-то в коде сделать
    
    service.get().subscribe((response: ResponseObject) => {...})


    Более того, вы можете делать tap (и любой друго pipe оператор) пока у вас есть обзёрвбл:

    service.get()
      .pipe(
        tap(...),
        map(...),
        whatever(...),
      ).subscribe((response: ResponseObject) => {...})


    Вам будет проще понять механизм работы обзёрвблов, если вы будите рассматривать обзёрвбл как функцию, а метод subscribe как способ выполнить эту функцию.

    Учитывая вышесказанное:

    const observable = service.get();
    observable.subscribe((result) => {...}); //выполнит запрос к серверу
    observable.subscribe((result) => {...}); //выполнит запрос к серверу еще раз
    // запрос к серверу будет инициироваться каждый раз когда будет выполняться функция subscribe
    Ответ написан
    2 комментария