• Как используя синтаксис ES-2015 class создать экземпляр который был бы функцией?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Полноценно можно сделать только используя Proxy, но работать будет только в окружении ES-2015 (большинство актуальных браузеров уже поддерживают)
    Не полноценно (зато будет работать в браузерах типа IE) - можно сделать через хак предложенный 0xD34F с возвратом своего объекта (функции) из конструктора

    Пример с Proxy:
    const TestClass = (function() {
        class TestClass {
            constructor() {
                this.calls = '';
            }
    
            toString() {
                return this.calls;
            }
        }
    
        Object.setPrototypeOf(TestClass.prototype, Function.prototype);
    
        function callTestClassInstance(el) {
            this.calls += String(el);
        }
    
        return new Proxy(TestClass, {
            construct(TestClass, args) {
                const instance = new TestClass(...args);
                const target = args => callTestClassInstance.apply(instance, args);
                Object.setPrototypeOf(target, TestClass.prototype);
                return new Proxy(target, {
                    apply(target, _, args) {
                        return target(args);
                    },
                    get(_, name) {
                        return instance[name];
                    },
                    set(_, name, value) {
                        instance[name] = value;
                        return true;
                    },
                    has(_, name) {
                        return name in instance;
                    },
                    deleteProperty(_, name) {
                        return delete instance[name];
                    },
                    defineProperty(_, name, descriptor) {
                        return Object.defineProperty(instance, name, descriptor);
                    },
                    getOwnPropertyDescriptor(_, name) {
                        return Object.getOwnPropertyDescriptor(instance, name);
                    },
                    ownKeys() {
                        return Object.getOwnPropertyNames(instance).concat(Object.getOwnPropertySymbols(instance));
                    }
                });
            }
        });
    })();
    Ответ написан
    Комментировать
  • Почему не вызывается функция при 2 запросе к серверу?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Потому что onLoadPage возвращает функцию, которую никто не вызывает, надо так:onLoadPage()(dispatch);
    Ответ написан
  • Как провести A/B тестирование с использованием cookie?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    У Вас должно быть 2 вариант куки, которые устанавливаются заранее, а на сервере должен вестись подсчет, сколько какой куки Вы уже выдали раньше. Если у пользователя нет куки, то выбираем какую ставить на основе этого подсчета. Проще говоря, первому посетителю Вы ставите куку А, потом 9 человек получают В.

    Для google analytics ставьте utm метки в url (можно на js через history API)
    Ответ написан
    Комментировать
  • Почему не работает клонирование canvas?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    А Вы в консоль заглядывать пробовали?
    canvas.clone is undefined
    Ответ написан
    Комментировать
  • Как отследить какие выполняются javascript при загрузки страницы?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    В dev-tools Chrome можно повесить брейкпоинт на дом элемент (на изменения атрибутов, на изменения потомков, на удаления). Щелкните правой кнопкой мыши по нужному dom элементу в dom инспекторе, и выберите в меню break on
    Ответ написан
    3 комментария
  • Почему nodejs в кластерном режиме показывает результат производительности хуже чем в одном инстансе?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    https://nodejs.org/dist/latest-v10.x/docs/api/clus...

    Сам по себе кластер, на всех ОС кроме винды, делает accept соединений в мастер процессе и передает воркерам уже установленное tcp соединение с клиентом, это позволяет балансировать нагрузку алгоритмом round-robin (каждому воркеру дается примерно равное количество соединений, так как они раздаются строго по очереди), но это же накладывает издержки на передачу файлового дескриптора соединения между мастер и воркер процессами при каждом соединении.

    Вариантов оптимизации тут 2:
    1. Nginx должен открывать соединения с бэкендом в режиме keep-alive. Так минимизируются издержки не только на передачу соединения воркеру, но и вообще на его открытие, что даст ощутимый прирост производительности под нагрузкой.
    2. Вместо модуля cluster использовать обычный child_process и управлять передачей соединений вручную, а точнее передавать не уже открытые соединения, а слушающий сокет. В этом случае балансировка будет происходить на уровне ОС. Как пишут в документации к cluster, это может привести к неравномерной загрузке воркеров, так как соединение будет доставаться тому воркеру, который первым успеет сделать accept. Зато уберет издержки на передачу каждого соединения между процессами. Но даже при этом варианте, keep-alive крайне желателен.
    Ответ написан
    1 комментарий
  • Какую версию IE поддерживать в коммерческих проектах?

    bingo347
    @bingo347
    Crazy on performance...
    Зависит от целевой аудитории.
    Где-то вопрос о поддержке IE уже просто не стоит, а скорее стоит какую версию safari поддерживать
    Где-то нужен хотя бы 11
    А где-то нужна даже 6
    Ответ написан
  • Проблема c CORS запросом, как исправить?

    bingo347
    @bingo347
    Crazy on performance...
    заголовки вида Access-Control-Allow-* - это заголовки ответа, их должен отправлять сервер в ответ на запрос
    притом если запрос OPTIONS (браузер шлет сам перед основным запросом для проверки прав), то сервер должен так же ответить этими заголовками, но со статусом 204 и без тела
    Ответ написан
    2 комментария
  • Как отключить скрипт для мобильников?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    подключите такой модуль к проекту:
    const appleDevice     = /iP(hone|od|ad)/;
    const applePhone      = /iPhone/i;
    const appleIPod       = /iPod/i;
    const appleTablet     = /iPad/i;
    const androidPhone    = /(?=.*\bAndroid\b)(?=.*\bMobile\b)/i;
    const androidTablet   = /Android/i;
    const windowsPhone    = /Windows Phone/i;
    const windowsTablet   = /(?=.*\bWindows\b)(?=.*\bARM\b)/i;
    const otherBlackberry = /BlackBerry/i;
    const otherOpera      = /Opera Mini/i;
    const otherFirefox    = /(?=.*\bFirefox\b)(?=.*\bMobile\b)/i;
    const sevenInch       = /(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)/i;
    
    function match(regex, target = navigator.userAgent) {
        return regex.test(target);
    }
    
    export const isAppleDevice = match(applePhone) || match(appleIPod) || match(appleTablet) || match(appleDevice, navigator.platform);
    export const isAndroidDevice = match(androidPhone) || match(androidTablet);
    export const isWindowsDevice = match(windowsPhone) || match(windowsTablet);
    export const isOtherDevice = match(otherBlackberry) || match(otherOpera) || match(otherFirefox);
    export const isSevenInch = match(sevenInch);
    export const isMobileDevice = isAppleDevice || isAndroidDevice || isWindowsDevice || isOtherDevice || isSevenInch;
    export const isEmulator = isMobileDevice && !isWindowsDevice && (match(/Mac/, navigator.platform) || match(/Win32/, navigator.platform));

    далее импортируйте нужный флаг, и проверяйте через if
    Ответ написан
    Комментировать
  • Require.context and lazy-loading?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    https://webpack.js.org/api/module-methods/#require...
    обратите внимание на 4й необязательный параметр mode, особенно на 'lazy' и 'lazy-once'
    Ответ написан
    4 комментария
  • Вопрос о новых веяниях и требованиях во фронтенде?

    bingo347
    @bingo347
    Crazy on performance...
    Для начала скажу об Html academy, что знаю.
    В начале года звали преподавать у них js + разрабатывать по нему курсы. Сразу скажу, что у меня впервые сложилось положительное впечатление от такого предложения, а не пошел я к ним по причинам не зависящим от них. Во-первых они дают базис, основы без которых Вы просто не сможете нормально разрабатывать, а освоить с этим базисом фреймворк большого труда не составит (про фреймворки ниже напишу).
    Во-вторых, хорошее впечатление у них составили люди, с кем удалось пообщаться, которые занимаются там составлением курсов и преподаванием - все как один не академики-теоретики, а практикующие разработчики с хорошим уровнем (а набирала в преподаватели Html academy в тот момент не ниже сеньера, предлагая соответствующую рынку зп).
    Ну и в-третьих, один раз собеседовал кандидата, имеющего за плечами только Html academy, обычно я негативно отношусь к кандидатом имеющим только курсы за плечами, но тут собеседуемый показал хороший уровень владения js.

    Теперь по фреймворкам.
    Не одному адекватному работодателю не нужен тупой фреймворкописатель без знания языка и нативного api, на которых этот фреймворк основан. В то же время, при знании js и DOM Api - Vue и React осваиваются за неделю, Angular за месяц. А без знания основ, может формочки ваять и сможете, но не больше. Так что учите сначала основы - js и нативное api браузера (DOM, CSSOM, ajax и т.д.), а уже потом беритесь за фреймворк.
    Ответ написан
    Комментировать
  • Как выделить все :focus в css с помощью регулярного выражения?

    bingo347
    @bingo347
    Crazy on performance...
    С регулярками на весь файл скорее всего будут проблемы, много чего может поломаться.
    Я бы сделал так:
    1. поставил бы модуль https://www.npmjs.com/package/css
    2. спарсил бы этим модулем css файл в AST дерево
    3.1. пробежался бы по всем селекторам в AST дереве в поисках селектора с :focus
    3.2. при нахождении нужного селектора, сделал бы что-то с ним (изменил, вырезал (если последний селектор в правиле, нужно вырезать все правило), что-то еще по вкусу)
    4. собрал модулем css AST дерево обратно в css код и записал бы в файл
    Ответ написан
    Комментировать
  • Как задать события в классах ES6?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    // мне кажется, что ждать полной загрузки страницы тут незачем
    document.addEventListener('DOMContentLoaded', () => {
        new Slider({
            images: ".slider__galary img",
            btnPrev: ".btnPrev",
            btnNext: ".btnNext",
            rate: false
        });
    });
    
    // хелпер для прослушивания событий
    class EventListener {
        constructor(ctx, handlers, target) {
            this.ctx = ctx;
            this.handlers = handlers;
            Object.keys(handlers).forEach(event => target.addEventListener(event, this));
        }
    
        handleEvent(event) {
            const {handlers, ctx} = this;
            const {type} = event;
            if(typeof handlers[type] !== 'function') return;
            handlers[type].call(ctx, event);
        }
    }
    
    class Slider {
      construnctor({images, btnPrev, btnNext, rate, time = 1000}) {
            this.images = document.querySelectorAll(images);
            this.i = 0;
            new EventListener(this, {
                click: this.prev
            }, document.querySelector(btnPrev));
            new EventListener(this, {
                click: this.next
            }, document.querySelector(btnNext));
            if(rate) {
                setInterval(() => this.next(), time);
            }
        }
        
        prev() {
            this.images[i].classList.remove("showed");
            this.i--;
            if(this.i < 0){
                this.i = this.images.length - 1;
            }
            this.images[i].classList.add("showed");
        }
    
        next() {
            this.images[i].classList.remove("showed");
            this.i++;
            if(this.i >= this.images.length){
                this.i = 0;
            }
            this.images[i].classList.add("showed");
        }
    }
    Ответ написан
    2 комментария
  • Как впустить в поток, поток получаемый из другого сервиса?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    без знания, что за либа предоставляет youtubeApi сделать адекватно проблематично, но можно сделать универсально:
    const {PassThrough} = require('stream');
    
    const youtubeStream = new PassThrough();
    youtubeApi.downloadVideo(
      'v=4P1-JwZF0Vo&t=4519s',
      chunk => youtubeStream.write(chunk),
      () => youtubeStream.end()
    );
    youtubeStream.pipe(res); // где res - выходной поток к клиенту
    Ответ написан
    1 комментарий
  • Не могу добавить папку в $PATH. Пишет Нет такого файла или каталога. В чем дело?

    bingo347
    @bingo347
    Crazy on performance...
    export PATH="$PATH:/bin/customscripts"
    Ответ написан
    Комментировать
  • Как проверить, что картинка существует?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ну во-первых, присваивание функции в img.load не даст никакого результата, если хотите повесить обработчик события, то нужно присваивать в img.onload

    Во-вторых, данный обработчик работает асинхронно, когда Вы делаете проверку, он еще не выполнился, а выполнится он только тогда, когда картинка загрузится

    Ну и наконец в-третьих, если картинки нет, то событие load не произойдет никогда, нужно проверять еще событие error, чтоб отследить ошибку загрузки, а заодно вешать таймаут, дабы не ждать загрузки вечность

    Проще всего это реализовать с промисами (если нужна поддержка старых браузеров - то добавьте полифил):
    // для начала я вынесу массив с разрешениями из функции, чтоб не создавать его для каждого вызова:
    var resolutions = ['maxresdefault', 'hqdefault', 'mqdefault'];
    function fetch_highest_res(videoid) {
      // сама функция будет возвращать промис, полученный сверткой массива resolutions
      return resolutions.reduce(
        function(promise, resolution) {
          // перехватываем только ошибку загрузки, если была успешная загрузка - просто отдаем ее дальше
          return promise.catch(function() {
            return new Promise(function(resolve, reject) {
              var img = new Image();
              // повесим таймаут в 3 секунды (если надо, поставьте больше), генерирующий ошибку
              setTimeout(reject, 3000);
              // отследим ошибку загрузки
              img.onerror = reject;
              // а в случае успешной загрузки отдадим результат
              img.onload = function() {
                resolve(resolution);
              };
              // и только когда навесили обработчики начинаем загрузку
              img.src = 'https://i.ytimg.com/vi/' + videoid + '/' + resolution + '.jpg';
            });
          });
        },
        // в качестве инициализирующего значения отдаем отклоненный промис
        // так как следующая картинка должна пробоваться только если не получилось загрузить предыдущую
        // а отслеживать мы это будем по ошибке загрузки
        Promise.reject()
      // ну и перехватим случай, если ничего не удалось загрузить
      ).catch(function() { return null; });
    }
    
    // ну и функция теперь у нас возвращает асинхронный результат в виде промиса
    // поэтому и получать его надо соответствующе
    fetch_highest_res('eei-soH5Gx8').then(function(resolution) {
      console.log(resolution); // hqdefault
    });


    P.S. сделал все в es5, ибо мало ли, Вам нужна поддержка старья, а сборкой Вы явно не пользуетесь...
    Ответ написан
  • Правильно ли изучать все и сразу?

    bingo347
    @bingo347
    Crazy on performance...
    учить что-то бесполезно, нужна практика а не зубрежка.
    выкиньте вообще все учебники пылится на полку, они не эффективны, придумайте себе проект и начните его делать, а там где уже попали в ступор - идите в справочники и учебники, так профит будет в разы больше

    ну и насчет распылятся сразу на несколько ЯП, тоже не стоит, в голове каша будет. лучше натренироваться досконально в чем то одном, а остальное уже после смотреть для общего развития
    иначе в голове возникнет каша, Вы ведь не изучаете в раз английский, немецкий и французкий? ну и с языками программирования так же
    Ответ написан
    Комментировать
  • Как воспользоваться callback для обработчика?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    function handleClick() {
        $('.photo').removeClass('active-element');
        $(this).addClass('active-element');
        $('.point li').removeClass('active-point').
        filter((index, item) => $(this).data('id') == $(item).data('id')).addClass('active-point');
        $('.about-text p').text($(this).data('text'));
        $('.about-site p').text($(this).data('info'));
        $('.about-site a').text($(this).data('website')).attr("href", "#");
    }
    
    $('.photo').click(handleClick);
    $('.point li').click(function() {
        $('.point li').removeClass('active-point');
        $(this).addClass('active-point');
        handleClick.call(this)
    });
    Ответ написан
    Комментировать