• Array.splice и Array.slice в JavaScript
    +3

    Array.splice это Array.splice — статический метод класса Array. Если нужно кратко записать метод экземпляра (Array.prototype.splice), то обычно используется запись Array#splice.

  • Опрос по инструментам фронтенда 2019 — результаты
    +1

    Секция scripts в package.json.

  • Оформляйте стили наведения, фокуса и активного состояния по-разному
    +1

    Зачем вообще показывать состояние фокуса, если пользователь не прикасался к клавише Tab? Это лишняя информация для него. Нужно делать так:
    На body висит класс _noFocusHighlight который прячет всё (почти всё, про исключения ниже) отображение фокуса, при нажатии на Tab он снимается и пользователь видит состояние фокуса, раз нажал на Tab — значит оно ему нужно. При любом клике, после которого document.activeElement указывает на body, возвращается класс _noFocusHighlight. Возможны некоторые исключения, например, текстовые поля, состояние фокуса на которых отображается даже если было получено мышкой.
    Вот код: тыц.

  • Ом-ням-ням и валидация данных
    0

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

  • Ом-ням-ням и валидация данных
    0

    Реализовал оба варианта. keypath подставляется сам когда есть вложенность. Вместо message можно использовать type, в таком случае сообщение об ошибке будет сформировано с учётом .or:


    om(om.custom({ validator, type: 'type1' }).or.custom({ validator, type: 'type2' }), type3);
    // бросит TypeError('Expected "type1" or "type2"')

    Примеры в сообщении выше тоже рабочие.

  • Ом-ням-ням и валидация данных
    0

    Привет. Можно научить понимать возвращаемую валидатором строку как сообщение об ошибке при неудачной проверке:


    om.number.and.custom(value => value > 18 || 'Вы ещё слишком маленький')

    Можно в этой строке некоторые простые замены делать, например, {keypath} заменять на место где случилась ошибка.


    Ещё вариант — научить .custom() понимать не только функцию, но и объект с функцией и строкой ошибки:


    om.number.and.custom({
        validator: value => value > 18,
        message: 'Вы ещё слишком маленький ({keypath})'
    });

    Если нужно такое, создайте issue чтобы я не забыл. Сделаю в скором времени.

  • React + Mobx: в чём смысл?
    0
    Ну да, просто тестировать имеет смысл на реалистичных сценариях.

    ну там вполне реалистично, 1-2 зависимости, можно увеличить до 1-3, но не более, это будет похоже на 99% ячеек в реальном приложении. А про глубину нет смысла думать, как я уже говорил, ячейке пофиг на какой она глубине, на скорости её обработки никак не отражается, это просто способ сделать их много.


    Ну там долго расписывать, какая именно часть его не понятна?

    в общих чертах вроде понял, вопрос уже другой: это реально даёт результат в плане ускорения или это пока просто эксперимент? Чем больше понимаю алгоритм, тем большее ощущение, что это никак не должно быть быстрее использования Set и тем более массива при малом числе зависимостей.

  • React + Mobx: в чём смысл?
    0
    Разные реализации по разному справляются с разным числом зависимостей. Ну грубо говоря indexOf на большом числе зависимостей может начать тормозить.

    так и я о том же. Глубину то ты зачем уменьшить хочешь? Ты не понимаешь, что увеличивать число зависимостей можно не трогая глубину?


    трекинг происходил как можно быстрее

    ну это понятно, я про идею алгоритма спрашивал.

  • React + Mobx: в чём смысл?
    0
    а в худшем — что-нибудь ломается капитально

    ok, на самом деле я немного о другом случае описанном здесь. А то о чём говоришь ты похоже из этой серии. Странно, но со мной такого ни разу так и не случилось, может мне очень повезло, а может что-то в моём фреймворке не даёт этому происходить. В любом случае хорошо, что ничего подобного больше не случится ни с $mol_atom, ни с cellx.


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

    так я и не спорю про разное число зависимостей, я про то, что замена большей глубины на большую ширину без изменения числа зависимостей ничего не даст. Так зачем ты это требуешь?


    но без indexOf

    выглядит довольно запутанно, плюс отталкивает slaves с разными типами значений (в masters как я понял тоже самое) и лишние итерации при переборе masters (if( !master ) continue). Set#has конечно чуть медленнее, но неужели вся эта дополнительная возня действительно даёт результат? Можешь поверхностно объяснить идею?

  • React + Mobx: в чём смысл?
    0

    Про глубину в очередной раз ответил чуть раньше.


    Чтоб можно было на полученные от бека данные вешать реактивные поля, и потом не париться тем, что перед JSON.stringify обратно на сервер эти реактивные поля нужно будет вычищать.

    я для подобного использую декоратор NonEnumerable.

  • React + Mobx: в чём смысл?
    0
    но когда стреляло — отрывало руки по локоть

    можно пример? Я находил у себя в приложении пару мест с таким лишним вычислением, там всё гладко было. Я именно намеренно искал, никаких проблем не возникало.


    И надобности в сильно глубоких деревьях мне встречать не приходилось

    вычисляемой ячейке где-то в середине цепочки вообще без разницы сколько там в глубину над или под ней. Твоё предложение менять число зависимостей ещё хоть как-то обосновано (ответил ниже), но я хоть убей не понимаю, что ты так вцепился в глубину дерева. Это же просто способ увеличить число ячеек в тесте.


    Трекинг большого числа зависимостей
    Инвалидация большого числа зависимых

    я вижу у тебя для хранения родительских и дочерних ячеек используется Set, has на котором, при достаточно большом количестве айтемов, будет заметно быстрей, чем indexOf на массиве (https://jsperf.com/array-indexof-vs-set-has/). Наверно, в таком кейсе твой вариант действительно будет быстрее. Я же выбрал массив, тк. при малом числе айтемов уже indexOf быстрее, плюс нативный for-of тогда ещё рано было использовать, а Set#forEach был заметно медленнее обычного цикла. Малое число зависимостей — это 99.9% случаев. Мой бенчмарк показывает как ведут себя библиотеки в этих 99.9%, ты же предлагаешь мне бенчмарк под 0.1% заявляя, что он будет более адекватным. Мне кажется ты всё же не прав.

  • React + Mobx: в чём смысл?
    0
    Корректность всё же важнее производительности

    С корректностью результатов в старом алгоритме всё отлично. Недостаток в лишнем вычислении при определённых условиях, которое в реальном приложении случалось крайне редко и совершенно не мешало.


    Или есть какие-то новые более адекватные бенчмарки?

    Не понимаю почему ты не веришь в адекватность такого бенчмарка. Ну вот уменьшу я глубину (число слоёв) одновременно увеличив количество ячеек в каждом слое и что дальше? Если количество вычисляемых ячеек по которым пройдёт сигнал будет тем же, то и результат будет абсолютно тем же.
    Все бенчмарки для такой библиотеки, скорей всего, можно разделить на два типа: 1 — скорость создания экземпляра ячейки, 2 — скорость прохождения сигнала по вычисляемым ячейкам. Остальное практически не имеет какого-либо смысла. Что ты предлагаешь ещё замерить? Скорость чтения не вычисляемой ячейки? Зачем?

  • React + Mobx: в чём смысл?
    0

    Начиная с v1.8 алгоритм тот же, что и в mobx. А на счёт менее продвинутого я бы поспорил, да в старом алгоритме есть один мелкий нерешаемый недостаток, но зато он минимум в 3 раза быстрее. В три раза медленнее — это лучшее, что я смог получить с нового алгоритма избавившись всего лишь-то от одного недостатка с которым вполне нормально жилось. Довольно сомнительное улучшение.

  • Неожиданный порядок инициализации наследованных классов в JavaScript
    0
    получаете поле объекта, а в python — это-таки поле класса

    ок, в общем-то я и и предлагаю использовать поля класса, на js будет так:


    class BaseTooltip {
        static template = 'baseTemplate'
        constructor(content) {
            this.render(content)
        }
        render(content) {
            console.log('render:', content, this.constructor.template)
        }
    }
    
    new BaseTooltip('content')
    
    class SpecialTooltip extends BaseTooltip {
        static template = 'otherTemplate'
    }
    
    new SpecialTooltip('otherContent')
    // render: content baseTemplate
    // render: otherContent otherTemplate

    Всё зависит от того — хочет ли он этот самый template, в какой-то момент, менять.

    в случае с шаблоном, если хочется что-то менять по условию, то стоит задуматься об использовании шаблонизатора и описывать эти изменения уже внутри шаблона.

  • Неожиданный порядок инициализации наследованных классов в JavaScript
    0
    что человек его не знает

    не претендую.


    Это, вроде как, не совсем то, чего хотел топикстартер

    почему? Вроде именно этого он и хотел. Какие недостатки у такого решения для его задачи?

  • Неожиданный порядок инициализации наследованных классов в JavaScript
    0

    Делить на ноль действительно плохо, не делайте так.

  • Неожиданный порядок инициализации наследованных классов в JavaScript
    0

    Python.

  • Неожиданный порядок инициализации наследованных классов в JavaScript
    +1

    Как обычно набежала куча любителей самоутверждения чтения документации. Хабру явно не хватает возможности отключать комментарии.


    v1vendi на многих ЯП ты бы получил ожидаемый результат:


    class BaseTooltip:
        template = 'baseTemplate'
    
        def __init__(self, content):
            self.render(content)
    
        def render(self, content):
            print('render:', content, self.template)
    
    BaseTooltip('content')
    
    class SpecialTooltip(BaseTooltip):
        template = 'otherTemplate'
    
    SpecialTooltip('otherContent')
    
    # render: content baseTemplate
    # render: otherContent otherTemplate

    , плюс все (которые я видел) обёртки имитирующие классы до ES6 вели себя именно так. Я тоже когда-то попался на этом хоть и заглядываю в спецификацию.


    UPD: одно из решений — использование статических свойств с обращением к ним через this.constructor.

  • Улучшайте свое знание JavaScript разбирая исходный код
    0

    А как же PrototypeJS и MooTools? Я довольно прилично прокачал свои знания js именно за счёт изучения внутренностей PrototypeJS.

  • Почему я не использую веб-компоненты
    +1

    В общем, я свою точку зрения высказал, принимать что-то или нет — дело твоё. Дальше препираться смысла не вижу, по моему опыту это не приводит ни к чему кроме потери времени. Удачи!

  • Почему я не использую веб-компоненты
    +1
    вам всё равно придётся открывать кучу веток этих самых кишок

    не прийдётся. Не обязательно и может даже не нужно обычные въюхи в ShadowDOM запихивать, он обязательно используется только для компонент вроде селекта, табов и подобного. Но кишки мешают больше не мне в devtools, а как раз при использовании таких компонентов в других фреймворках самим этим фреймворкам.


    Не использоваться фреймворки, которые сложно друг с другом интегрировать.

    ага, вот и я как раз про это: фреймворки на основе веб-компонентов максимально безболезненно интегрируются друг с другом. Причём это вполне естественно и не выглядит как совмещение единорога с китом. Сейчас интеграция заключается лишь в том, чтобы подружить полифилы, когда они станут не нужны, никакой интеграции вообще не нужно будет.


    Почему бы ей не захотеть не только единый стиль, но и единое поведение, и единую реализацию, и единый фреймворк?

    веб-компоненты с большой вероятностью проживут намного дольше, чем любой из существующих сегодня фреймворков, так зачем привязывать себя к какому-то из них, ждать когда он отомрёт и по новой переписывать каждую рюшечку? Если ui-библиотека сделана на веб-компонентах, то пусть разработчики использующие её пишут на чём им удобно.


    Ну конечно, и ленивый реактивный рендеринг к ним легко прикрутить?

    если ты про то, что реализовано в mol, то меня это не впечатлило, я против реализации чего-то подобного на уровне фреймворка. По крайней мере твои аргументы меня совсем не убедили. Подобное нужно реализовывать на уровне конкретного компонента, например, строки датагрида.


    Не усложнит.

    давай с аргументацией, окей? Почему ты думаешь, что найти разработчика на какой-то конкретный фреймворк так же легко как на любой из популярных на выбор кандидата? Например, насколько легко находить разработчиков на mol?


    Это какие? Когда я последний раз смотрел — их все задепрекейтили.

    ну видимо когда-то предложат что-то на замену или достаточно того, что осталось, я сейчас больше про общую идею, а не про текущую её реализацию, которая пока да, не идеальна. Сам я из веб-компонентов использую только CustomElements и HTMLTemplates. ShadowDOM полноценно не полифилится, а существующие недополифилы сильно жрут производительность. Поэтому я не особо в курсе что там с селекторами. Использую привычный БЭМ.


    о чём вы

    применяйте

    я себя лет на 20 старше чувствую)). Зачем вообще на хабре все выкают? В офисах и на конференциях все на ты, а здесь ощущение, как будто сплошные доктора наук собрались).

  • Почему я не использую веб-компоненты
    –2
    Насчёт кишок я не понял о чём вы

    я про внутренний dom компонента, зачем он мне торчащий наружу.


    Неймспейсы и маглинг имён решают проблему конфликтов не хуже изоляции.

    хуже, глобальные стили протекают внутрь компонента.


    Представь ситуацию: крупная компания, количество фронтенд-команд перевалило за десяток, каждая сама выбирает удобный ей фреймворк и базовый набор стилей. Можно, конечно, определить корпоративный стандарт, но это существенно усложнит поиск новых разработчиков. Кроме того проекты достаточно долгоживущие, фреймворки отмирают быстрее. При этом компания хочет свой корпоративный стиль, свои компоненты, отличающиеся от стандартных, часто не только цветом. Что делать? Разрабатывать и поддерживать библиотеки компонентов под каждый используемый фреймворк? Дороговато выходит.
    Или другая ситуация: ты работаешь в компании A и разрабытываешь библиотеку компонент на фреймворке X. А потом либо меняется компания A и в компании B используется фреймворк Y, либо фреймворк X отмирает и все хотят Y. Куча работы вылетает в трубу, а ведь класный набор компонентов получился, хотелось бы дальше применять.
    Веб-компоненты тут идеальное решение, ShadowDOM спрячет лишний внутренний dom, который теперь не будет мешать фреймворкам, глобальные стили не будут заставлять компонент расползаться, но, в то же время, есть хитрые css-селекторы позволяющие при необходимости что-то поменять внутри. Другими словами, получающиеся компоненты полностью автономны, так же как и уже встроенные в браузер input, select, video и тд. Из коробки веб-компоненты не очень удобны, но большинство существующих проблем решается легковесной обёрткой, опять же никак не мешающей существующим фреймворкам.

  • Почему я не использую веб-компоненты
    0

    Как с помощью библиотек реализовать элемент с изолированным css и не торчащими наружу кишками (ShadowDOM)?

  • Почему я не использую веб-компоненты
    +2
    тормоза лейаута после ресайза

    если у вас лейаут считается в js-e, то это будет тормозить на любом фреймворке.

  • Svelte 3: Переосмысление реактивности
    0
    Выше уже разобрались, что $$invalidate ставится только для переменных используемых в шаблоне и реактивных объявлениях. Всё норм)
  • Svelte 3: Переосмысление реактивности
    0
    только для переменных, которые задействованы в шаблонах

    да, тоже подумал об этом после отправки сообщения. Тогда всё норм, единственно что переменная может использоваться в шаблоне, но быть внутри условия, которое сейчас неактивно. Тогда $$invalidate сработает, но вряд ли там что-то страшное (изменение DOM) произойдёт.

  • Svelte 3: Переосмысление реактивности
    0

    Разве не будет ситуаций когда эти $$invalidate ставятся там где совсем не надо? Если уж есть свой компилятор, то почему бы не ввести новое ключевое слово? Например, я когда-то делал плагин для babel который заменял такой код:


    cell firstName = 'Matroskin';
    cell lastName = 'Cat';
    
    cell fullName = firstName + ' ' + lastName;
    
    console.log(fullName);

    на такой:


    const cellx = require('cellx');
    const firstName = new cellx.Cell('Matroskin');
    const lastName = new cellx.Cell('Cat');
    
    let fullName = new cellx.Cell(() => firstName.get() + ' ' + lastName.get());
    
    console.log(fullName.get());

    Будут, конечно, проблемы с поддержкой в IDE, но наверно можно какие-нибудь плагины для популярных IDE организовать. Правда сам не пробовал, забросил эту тему.

  • Как реализовать язык программирования на JavaScript. Часть 1: Парсер
    0
    Благодарю, пригодится.
  • Как реализовать язык программирования на JavaScript. Часть 1: Парсер
    0

    Ну поменять так:


    const reSuperCall = RegExp(`super(?:\\.(${namePattern}))?!|`, 'g');

    Вообще как только что-то усложняется, ничто не мешает делать без регулярок. В примере выше имя больше нигде не повторялось, мне не было смысла отделять его от super, но в соседнем парсере повторялось и _readName ниже использовался в этих местах, написанных уже как обычно:


    const reName = RegExp(namePattern + '|', 'g');
    
        _readName(): string | null {
            reName.lastIndex = this._pos;
            let name = reName.exec(this.contentNodeValue)![0];
    
            if (name) {
                this._pos = reName.lastIndex;
                return name;
            }
    
            return null;
        }
  • Как реализовать язык программирования на JavaScript. Часть 1: Парсер
    0
    мы будем обязаны изменять все регулярные выражения, а не одну функцию

    зачем?

  • Как реализовать язык программирования на JavaScript. Часть 1: Парсер
    0
    Не пробовать использовать регулярных выражений для парсинга. Они просто не работают.

    Много разных парсеров написал подобным образом, с регулярками сначала действительно не понятно было как их применять даже там где они казалось бы в тему. Там проблема собственно в том, что регулярка не найдя совпадение в нужной позиции начинает искать его на следующих. Можно обрезать строку и использовать ^, но постоянные обрезания огромной строки плохо влияют на карму парсера. Придумал вариант с добавлением в конец регулярки | — если на первой позиции совпадение не найдено, происходит гарантированной совпадение с пустотой, ну и проверяем match[0], если пусто, то совпадения нет. Пример:


    const reSuperCall = /super(?:\.([a-zA-Z][\-\w]*))?!|/g;
    
        _readSuperCall(): ISuperCall | null {
            reSuperCall.lastIndex = this._pos;
            let match = reSuperCall.exec(this.template)!;
    
            if (match[0]) {
                this._pos = reSuperCallOrNothing.lastIndex;
    
                return {
                    nodeType: NodeType.SUPER_CALL,
                    elementName: match[1] || null
                };
            }
    
            return null;
        }

    Это мелочь конечно, но может кому-то пригодится, так как ситуации когда хочется скатиться к регулярке довольно часто бывают.


    И второе: функциональный стиль здесь действительно удобен, но посмотрите ещё раз пример с InputStream — в нём нужно каждой функции передавать общее состояние, это организуется через замыкание и для этого внутри функции при каждом вызове создаётся множество других функций и чем сложнее парсер, тем их будет больше. Если один в один переписать в виде класса (общее состояние будет в this или просто без класса передавать его каждый раз в переменной), то производительность резко подскакивает. В некоторых случаях в десятки раз.

  • Maraquia — ORM для MongoDB
    0
    Добавил.
  • Веб-компоненты в реальном мире
    0
    только если они не имеют своих зависимостей

    Ладно, убедили), проблема есть, но всё же при использовании префиксов она совсем незначительна.


    Здесь помог бы typescript

    Не на 100%, как я уже сказал, браузеры могут добавлять свои нестандартные свойства/методы для элементов.

  • Веб-компоненты в реальном мире
    +1
    Может хорошей практикой считать не регистрировать компоненты в UI-библиотеках, просто экспортировать класс и пусть использующий сам регистрирует под нужным ему именем. Я все компоненты сам писал так что такой проблемы не было, была проблема с именами атрибутов-свойств: уже существующих свойств дофига, у разных элементов они немного отличаются, плюс немного отличаются от браузера к браузеру. В результате можно легко переопределить существующее имя и получить какой-нибудь непонятный баг.
  • Веб-компоненты в реальном мире
    0

    Обычно элементам добавляется какой-то префикс, например здесь добавляют paper.

  • Веб-компоненты в реальном мире
    0
    вы ничего уже с этим сделать не сможете

    Можно унаследовать от такого компонента с изменением имени.

  • Когда использовать var, let и const в Javascript [перевод статьи Tyler’а McGinnis]
    –1
    я рекомендовал бы вам попробовать такой стиль

    если что, то я уже больше 10 лет повседневно работаю с javascript/typescript и перепробовал очень многие вещи. Повсеместный const — одна из первых фич, которые я попробовал при появлении babel и навязал её использование не в одном проекте. Так что я то как раз полноценно с обоими вариантами поработал).
    Такие вещи действительно нужно именно пробовать и порой достаточно длительное время, приведу хороший пример: первый рабочий день в новой компании, открываю код и, о ужас:


    x == 1

    Какое равенство нужно использовать в сравнениях, двойное или тройное? Уверен 99% смело ответят, что тройное, а оставшийся процент — неопределившиеся новички. Я тоже был исключительно за тройное. Спрашиваю — "Ребят, что за г в этом файле?", — "А у нас везде двойное равенство", — "Вроде компания серьёзная, а вы тут дикие какие-то. Вам Интернет отключили? Весь мир исключительно тройное использует!". Мне объяснили как нужно использовать двойное равенство не получая с этого стандартных минусов и в чём с этого будет плюс. И вроде понятно всё объяснили, там и объяснять то нечего, но я подумал: "ересь какая-то", говорю: — "Ну пофиг, буду делать как у вас тут принято, мне же не жениться на местном коде, но я остался при своём мнении", — "Окей, попробуй, посмотрим, что ты скажешь через пол года". Больше это не обсуждалось, но менее чем через пол года при рефакторинге личного кода я добровольно заменял тройное равенство на двойное. Тоже дикий совсем стал). До сих пор с удовольствием пользуюсь этой фичей в личных проектах, но ни разу даже не пытался где либо её пропихнуть, просто знаю, за такие мысли сразу камнями закидают, никто даже на секунду не задумается про попробовать, просто категоричное нет от всей команды. А там как раз была целая команда с удовольствием использующая эту фичу и как мне кажется большинство приходило в неё с теми же мыслями, что и я.


    Та же ситуация с повсеместным const, все его используют, а тут какой-то вася какую-то ересь порет, и ладно бы объяснили и успокоился, но нет же, не унимается. Уже вон и в карму наплевали, действительно, да что вообще этот вася возомнил о себе!)). Мне вот как-то и в голову не приходило плевать в карму за отличающееся от моего мнение которое человек пытается спокойно обосновывать. Ну да пофиг, мне ж за карму на хабре не платят, хоть в минус загоняйте. Интересно другое: если завтра какой-нибудь фейсбук/гугл начнёт предлагать подобную ересь и использовать её у себя, то ситуация будет кардинально отличаться — нехотя, но начнут пробовать, а там глядишь и через пару лет станет общественным стандартом. Легчайше! Всего несколько лет назад кто бы мог подумать, что писать js, html и css в одном файле будет считаться нормой. Вот я бы такое предложил? Да сожгли бы!). Вот и получается победа общественного мнения и хайпа на собственным мозгом каждого.
    Меня же та ситуация с двойным равенством научила спокойней относится ко всяким странным идеям, в каждом новом проекте я стараюсь попробовать что-нибудь новое, пусть и странное, хотя чаще это относится к каким-то архитектурным решениям, а не к такой мелочи, что мы здесь обсуждаем. Просто хотел показать альтернативный вариант, но, к сожалению, у многих это вызывает лишь желание меня заткнуть.

  • Когда использовать var, let и const в Javascript [перевод статьи Tyler’а McGinnis]
    0

    Сделал так:


    let a = 5;
    let b = 10;
    let c = 10;
    
    let x = (a = b ? 1 : a == c ? 2 : 3);
  • Когда использовать var, let и const в Javascript [перевод статьи Tyler’а McGinnis]
    0
    Во втором случае typescript (или vscode) убрал лишние скобки.
  • Когда использовать var, let и const в Javascript [перевод статьи Tyler’а McGinnis]
    0

    Разве это не какое-то известное правило? Раньше, когда использовал javascript, у меня eslint подсвечивал такое заставляя добавлять скобки, причём я специально не настраивал это, то есть у многих должно работать как-то так же. Сейчас typescript как выяснилось не ругается, но при форматировании сам добавляет скобки. В данном случае добавил так:


    let a = 5;
    let b = 10;
    
    console.log((a = b ? 1 : 2));