• В чем разница между keepass, keepassx и keepassxc? И существует ли синхронизация баз паролей?

    dewil
    @dewil
    кратко о себе
    У KeePassXC есть внутренний механизм, называется KeeShare.
    Суть в том, что можете на любой папке в базе паролей активировать и эта папка будет синхронизироваться с другой базой. Весьма удобно, к примеру, для корпоративного использования.
    Ответ написан
    Комментировать
  • В чем разница между keepass, keepassx и keepassxc? И существует ли синхронизация баз паролей?

    psbinfo
    @psbinfo
    keepass - оригинал для винды
    keepassx - мертв копия
    keepassxc - живая копия/ответвление для линуха и для винды.
    Ответ написан
    Комментировать
  • В чем разница между keepass, keepassx и keepassxc? И существует ли синхронизация баз паролей?

    Robur
    @Robur
    Знаю больше чем это необходимо
    Кладете базу в дропбокс и будет синхронизация
    Ответ написан
    Комментировать
  • Стоит ли использовать esbuild для сборки фронта сегодня?

    @deliro
    Я пару недель назад перевёл сборку фронта с rollup на esbuild. Время сборки упало с 13с до 200мс (x65 ускорение). У коллег на M1 это время стало вообще 40мс

    Из минусов заметил только отсутствие таргета ES5 (ну как заметил, об этом в доках пишут везде). Кстати, перевод таргета на ES6 уменьшил размер бандла незначительно (в основном за счёт сокращения function() в ()=>)

    Больше проблем нет
    Ответ написан
    2 комментария
  • Хорошие онлайн-библиотеки, где есть книги по IT?

    Viji
    @Viji
    DevOps Engineer
    заходите на ya.ru , пишите название книги c добавкой формата и много чего можно найти !
    Ответ написан
    Комментировать
  • Есть ли замена Quokka.js?

    boratsagdiev
    @boratsagdiev
    https://runjs.app/

    Хотя лицензия есть и там, но за ней просто скрыты фишки типа npm-пакетов и тайпчекинга, плюс на несколько компьютеров.
    Ответ написан
    1 комментарий
  • На собеседовании сказали, что не все функции - замыкания. Так ли это?

    wapster92
    @wapster92 Куратор тега JavaScript
    Kyle Simpson дал хорошее определение замыкания, вообще советую его книги для прочтения.
    Замыкание — это когда функция умеет запоминать и имеет доступ к лексической области видимости даже тогда, когда эта функция выполняется вне своей лексической области видимости.
    Ответ написан
  • На собеседовании сказали, что не все функции - замыкания. Так ли это?

    Alexandroppolus
    @Alexandroppolus
    кодир
    По версии Ильи Кантора, глобальная функция при создании записывает себе лексическим окружением (Scope) глобальный объект, а в момент выполнения обращается к Scope.
    globalFunc.[[Scope]] = window;

    то есть формально да, это замыкание.

    но практического значения это не имеет, потому что глобальная функция с тем же успехом могла не записывать global себе в Scope, и при выполнении обращаться просто к global, который, к тому же, не ликвидируется сборщиком мусора

    upd: заметим, что глобальных объектов может быть несколько, например, ифреймы на странице, или контекст в нодовском модуле VM. Тогда замыкание глобальных переменных (как в примере из вопроса) таки имеет смысл.
    Ответ написан
    3 комментария
  • На собеседовании сказали, что не все функции - замыкания. Так ли это?

    @lazarevBoris
    Тред просто огонь!:)
    Дело в том, что такой же спор (из 8 страниц, на эту же тему) был не так давно на другом ресурсе, где мудрый дядька под ником "javascript" объяснял окружающим (которые тоже уперлись рогом, как и многие здесь), почему в js по факту всё является замыканием.
    Поэтому было крайне интересно, чем же и здесь дело закончится.
    И в очередной раз было доказано, что где бы ни была объявлена функция (а начиная с es6 и let - и блок кода) - она образует замыкание с цепочкой внешних лексических сред (или хотя бы одной LE), что полностью соответствует определению, предысторию которого хорошо описал Александр.
    Что наглядно изобразил Alexandroppolus (надеюсь, вы не будете против, если я достану ваш пример из jsfiddle и размещу здесь, чтобы он не пропал с течением времени):

    description:
    функция, созданная внутри iframe, замкнула внутрифреймовую глобальную переменную, и продолжает работать, даже когда фрейм удалили. Кнопкой frameValue можно убедиться, что в window той переменной нет.

    html:
    <script>
      var globalValue = 1000;
      var globalCounter = function() {
        return globalValue++;
      };
    </script>
    <div>
      <button>iframe counter</button>
      <button>globalCounter</button><br >
      <button>frameValue</button>
      <button>globalValue</button>
    </div>

    JS:
    const iframeHTML = 'iframe...<' + `script>
      var frameValue = 1;
      var counter = function() {
        // debugger;
        return frameValue++;
      };
      
      window.parent.iframeCounter = counter;
    <` + '/script>';
    
    function createTempFrame() {
    	const blob = new Blob([iframeHTML], {type: "text/html"});
      const frm = document.createElement('iframe');
      frm.src = URL.createObjectURL(blob);
      
      document.body.appendChild(frm);
      
      setTimeout(() => {
      	document.body.removeChild(frm);
      }, 900);
    }
    
    window.onload = function () {
      const buttons = document.querySelectorAll('button');
      
      buttons[0].onclick = function() {
        alert(iframeCounter());
      };
    
      buttons[1].onclick = function() {
        alert(globalCounter());
      };
      
      buttons[2].onclick = function() {
        alert(window.frameValue);
      };
      
      buttons[3].onclick = function() {
        alert(window.globalValue);
      };
     
      createTempFrame();
    };


    Так что да, автор треда, который ходил на собеседование, был прав, замыкание в его примере есть.
    Ответ написан
    1 комментарий
  • На собеседовании сказали, что не все функции - замыкания. Так ли это?

    @Barrakuda74
    Нет, не так. Ваш ответ был верным.
    Любая функция вкупе с лексическим окружением образует замыкание.
    Когда создаётся глобальное окружение (иначе говоря = начинается выполнение скрипта) - javascript создаёт лексическое окружение, в котором и будут храниться переменные и функции глобального контекста. Когда вы создаёте свою функцию в глобальном контексте, она замыкается на этом же лексическом окружении - лексическом окружении глобального контекста. Как видите, всё ОЧЕНЬ просто.

    Держитесь подальше от таких контор, где собеседуют такие "специалисты".
    Есть, конечно, вероятность, что вас HR собеседовала или техничка, но маловероятно.
    Всегда нужно стремиться в те компании, где вы будете расти как программист, а не деградировать.
    В галерах, где тимлид не знает о том, что такое замыкание, никакого роста, как вы понимаете, ожидать не приходится.

    p.s.: смотрю у многих ответы далеки от реальности, но это скорее всего из-за того, что ваш вопрос под тегом "Простой", поэтому получили набег джунов, только что вылупившихся из яйца.
    Ответ написан
  • На собеседовании сказали, что не все функции - замыкания. Так ли это?

    snaiper04ek
    @snaiper04ek
    Не стреляйте в эникея, он админит как умеет
    парень. Всё равно ты будешь использовать ту терминологию, которую используют на работе. Если там под замыканием подразумевается замыкание с инкапсуляцией, то после того как тебе сказали что "твой код - говно", было два варианта: 1)поговорить о терминах либо со ссылкой на официальную документацию, либо вместо с собеседником вывести определение исходя из смысла понятия, не прибегая к авторитетам вообще. 2) Сказать о том, что прочитал такое определение у %авторитет%, и сказать, что готов использовать то, которым пользуетесь вы на работе.

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

    Есть второй вариант: собеседник тебе говорит: "Ахтунг! Замыкание используется не просто для того, чтобы спасти переменную от удаления! Это ещё и способ сокрытия данных: замыканием можно использовать локальную глобальную переменную, вместо того чтобы использовать просто глобальную переменную, или же городить отдельный класс."
    В этом случае всё твое определение идёт в пешее эротическое, и ты соглашаешься, что для этого придётся обернуть функцию в функцию, чтобы у тебя была функция с локальными переменными, которые будут глобальными для этой функции в функции.
    Ответ написан
    13 комментариев
  • На собеседовании сказали, что не все функции - замыкания. Так ли это?

    @Arlekcangp
    Разработчик, Лид, Архитектор ПО
    Похоже вас поймали на том что в js кто-то решил переопределить термин "замыкание"... Т к javascript далеко не первый язык, в котором есть нечто, претендующее называться термином "замыкание", то следует в первую очередь рассмотреть общее определение. Возьмём его из википедии:

    Замыкание (англ. closure) в программировании — функция первого класса, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся её параметрами. Говоря другим языком, замыкание — функция, которая ссылается на свободные переменные в своей области видимости.
    Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе.
    Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. Синтаксически это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции.
    В случае замыкания ссылки на переменные внешней функции действительны внутри вложенной функции до тех пор, пока работает вложенная функция, даже если внешняя функция закончила работу, и переменные вышли из области видимости.[1]
    Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде). Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.


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

    In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function[a] together with an environment.[1] The environment is a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.[b] Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.


    О! А тут нет никаких "функций, вложенных в функцию" и нет никаких "создающихся каждый раз" Хм... Интересно. Ну за то есть абзац о том как появились замыкания:

    The concept of closures was developed in the 1960s for the mechanical evaluation of expressions in the λ-calculus and was first fully implemented in 1970 as a language feature in the PAL programming language to support lexically scoped first-class functions.[2]

    Peter J. Landin defined the term closure in 1964 as having an environment part and a control part as used by his SECD machine for evaluating expressions.[3] Joel Moses credits Landin with introducing the term closure to refer to a lambda expression whose open bindings (free variables) have been closed by (or bound in) the lexical environment, resulting in a closed expression, or closure.[4][5] This usage was subsequently adopted by Sussman and Steele when they defined Scheme in 1975,[6] a lexically scoped variant of Lisp, and became widespread.


    Ага. Оказывается первоначально они появились в такой не конвенциональной, с сегодняшней точки зрения VM, как SECD... И их создатель прямо говорит, что это код плюс данные. Далее термин применяют к лямбда-выражениям. Ничего не говорится, должны ли эти выражения возвращаться функцией, или достаточно того, что бы они захватывали переменные из своего лексического (или динамического, как в common lisp) окружения. Далее нам сообщают, что некие мистеры, Сасман и Стил, спустя каких то 11 лет добавили это в свой язык Scheme... Ну что же. Посмотрим замыкания в Scheme... А именно откроем книгу Сасмана и соавторов "Структура и интерпретация компьютерных программ" или "SICP" Первый раз (исключая содержание) слово "замыкание" встречается в главе 2 "Поcтроение абстракций c помощью данных"


    Важная идея в работе с составными данными — понятие замыкания (closure): клей для
    сочетания объектов данных должен позволять нам склеивать не только элементарные
    объекты данных, но и составные.


    Но, как выяснилось, это не те замыкания... Это замыкание в том смысле, что структуру одного типа (в данном случае пары) могут ссылаться на самих себя. И это то как термин "замыкание" понимают математики. Далее в SICP никаких других определений замыканий нет (несмотря на то, что само их использование конечно же есть) Ну ничего не остаётся как посмотреть что же сегодня называют замыканиями в языке Scheme... Гугл по этому запросу выдал первой ссылкой: https://www.cs.utexas.edu/ftp/garbage/cs345/schint....
    Цитирую:

    Procedures are Closures
    Scheme procedure's aren't really just pieces of code you can execute; they're closures.

    A closure is a procedure that records what environment it was created in. When you call it, that environment is restored before the actual code is executed. This ensures that when a procedure executes, it sees the exact same variable bindings that were visible when it was created--it doesn't just remember variable names in its code, it remembers what storage each name referred to when it was created.

    Since variable bindings are allocated on the heap, not on a stack, this allows procedures to remember binding environments even after the expressions that created those environments have been evaluated. For example, a closure created by a lambda inside a let will remember the let's variable bindings even after we've exited the let. As long as we have a pointer to the procedure (closure), the bindings it refers to are guaranteed to exist. (The garbage collector will not reclaim the procedure's storage, or the storage for the let bindings.)

    Here's an example that may clarify this, and show one way of taking advantage of it.

    Suppose we type the following expression at the Scheme prompt, to be interpreted in a top-level environment:

    Scheme> (let ((count 0))
               (lambda ()
                  (set! count (+ count 1))
                  count)))

    ##

    Evaluating this let expression first creates a binding environment with a binding for count. The initial value of this binding is 0. In this environment, the lambda expression creates a closure. When executed, this procedure will increment the count, and then return its value. (Note that the procedure is not executed yet, however--it's just created.) This procedure, returned by the lambda expression, is also returned as the value of the let expression, because a let returns the value of its last body expression. The read-eval-print loop therefore prints a representation of the (anonymous) procedure.


    Что имеем ? В Scheme - вообще любая функция - это замыкание! Т к она всегда захватывает контекст, даже если там пусто!. Что видим в коде ? Ну с точки зрения Scheme тут конечно вложенная функция, т к let - это на самом деле lambda, но так происходит потому, что в Scheme нет переменных в понимании js. В js же можно считать, что глобальный контекст - результат действия нечто, что эквивалентно let. Захватывает ли любая функция в js этот контекст ? Не знаю. Но точно знаю, что в вашем примере это определенно так - х часть контекста, который захватывается функцией. Кто хочет поспорить - идите спорьте с создателями Scheme (скажите, когда попкорн покупать, я посмотрю как вас пороть будут. Набежало тут вайтишников =)) Кто то может сказать "а вот у нас в js замыкания определяются не так" На что я отвечу: знаете, товарищи, а идите ка вы лесом! Если есть однажды созданный и определенный термин, нужны весьма веские причины что бы менять его определение. Желания левой ноги очередного вайтишника тут не достаточно.
    Ответ написан
    30 комментариев
  • Npm, Webpack, NodeJs с чего начать?

    @disgusting-dev
    "Один ли я такой" - нет, все такие, сложные конфиги и строки кода пишутся не одним человеком и не за один день. Плюс есть когнитивная ошибка, что эти строки написаны умными людьми - такое может быть не всегда и большие размеры могут быть неоправданны

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

    npm - ну да, он такой, с большим кол-вом дубликатов. Справедливости ради, такими являются все открытые пакетные менеджеры в зависимости от активности сообществ языков, тот же pip у питона или rust crates могут напоминать npm. Сильные дубликаты со временем уходят, т.к. появляется общий кодстайл сообщества, где все со временем стремятся использовать только одну библиотеку

    Я бы советовал идти от простого к сложному - если какой-то шаг можно пропустить, то пропускай. например, webpack идет пре-конфигурированный для многих фреймворков, его можно не касаться, некоторые фреймворки имеют удобный CLI, который дает возможность сразу предустановить самые нужные библиотеки и больше ничего не трогать там

    Ну или можно иначе - начать с голого html-js-css и потом постепенно прикручивать к ним сверху инструменты, параллельно понимая, для чего они все нужны
    Ответ написан
    Комментировать
  • Npm, Webpack, NodeJs с чего начать?

    @deliro
    Фронт развился в какую-то неправильную сторону, это правда
    Вкатиться на фронт очень сложно, это тоже правда. Причём, необоснованно сложно.

    Я бы выделил два пути, как можно въехать во всё это:
    1. Создать приложение на Vue или React по туториалам, затем разобраться, как и зачем оно всё
    2. Разобраться как и зачем оно всё (aka Vanilla JS), потом заняться реактами

    Имхо, вариант №2 предпочтителен и более прост, потому что на варианте №1 есть огромный шанс застрять, никогда не разобравшись, как оно работает а при любых нешаблонных ошибках поднимать лапки.

    Что здесь нужно понимать:
    1. Есть разные версии ES (ecmascript), они все обратносовместимые. Программист может писать на любой версии, какая ему нравится. Обычно берут последнюю стабильную

    2. Для проекта обычно есть две версии ES: та, на которой пишут программисты и та, которая исполняется в браузере или в ноде (об этом позже). Например, программист пишет на ES8, а код транслируется на ES5. Это позволяет использовать последние предсмертные хрипы писки моды JS при этом запуская всё на древнейшем говне вроде IE11. Перегонкой кода из JS/TS одной версии в JS другой версии занимается транспилятор: babel / esbuild / swc

    3. Новые версии JS содержат расширения стандартной библиотеки, которых нет в старых браузерах (например Array.from, Object.entries и т.п.). Эти дырки затыкают полифиллы, они же shims. Самая популярная дырозатыкательная машинка — corejs

    4. Весь код очевидно не пишется в одном файле и может быть написан на TypeScript (он же TS), JSX/TSX (реактовый синтаксис). Всё это нужно собрать в один или несколько файлов, то есть скомпоновать. Этим занимается bundler: часть webpack / esbuild / spark / etc.

    5. Этот же парень отвечает за то, чтобы та тысяча библиотек, что лежит в node_modules, попала в итоговый условный main.js, но не целиком, а только то, что используется. Последнее называется tree shaking (типа навозную кучу node_modules потрясли как дерево, что упало — то не нужно)

    6. (то самое "позже) Код может исполняться не только в браузере пользователя, но и на сервере без браузера вообще. Это нужно для SSR aka Server Side Rendering. SSR — это такой глобальный вонючий костыль для SEO. Дело в том, что стандартные SPA приложения содержат один DOM элемент, куда цепляется всё остальное приложение вроде реакта или вью, которое уже содержит всю вёрстку прямо в JS. Но не все поисковики согласны с таким подходом и некоторые (не будем показывать пальцем на яндекс) не умеют выполнять JS и индексируют только тот самый единственный DOM элемент, который существует на этапе отдачи страницы в браузер. Это уже потом к нему JS движком дорисовывается весь остальной сайт. Соответственно, сайт индексируется от слова "никак", а некоторым это важно. Например, когда SPA — это не админка. Для этого есть два выхода: страницы, важные для SEO, рендерить чем-то не-реактовым или сделать SSR — делать за яндекс работу на сервере (на ноде), представляя в уме, что у нас есть DOM и браузер (на самом деле нет), на выходе получать начальное состояние HTML, отдавать его клиенту (браузеру или поисковому роботу), а JS'ом её т.н. "гидрировать", иными словами — оживлять.

    7. webpack отвечает за всё вот это сверху в том или ином виде. Это такой кухонный комбайн, в который вкидываешь кучу хлама в одном виде, а получаешь другую кучу хлама в другом виде.

    Начать советую с parceljs, который сильно проще в освоении, чем webpack. И на написании кода максимально без библиотек.
    Ответ написан
    1 комментарий
  • Как снести все скрипты на странице?

    @GrayHorse
    Запретить выполнение JS кода (как инлайн, так и загружаемого) можно с помощью Content Security Policy (CSP) заголовков, как это делают NoScript расширения, в частости, uBlock Origin.

    Хотя не уверен, что в таком случае можно выполнить свой код в контексте веб страницы (не в в контексте контент скрипта), хотя, вероятно, можно разрешить сделать это, указав hash/nonce своего кода, в качестве разрешенного к выполнению (опять же — в CSP заголовке).
    Ответ написан
    Комментировать
  • Как снести все скрипты на странице?

    zkrvndm
    @zkrvndm Автор вопроса
    Архитектор решений
    Спасибо Aetae за подсказанное решение, которое работает в Firefox:
    document.wrappedJSObject.write(''); document.close();

    Если запустить метод из контент-скрипта в своем расширении еще до начала отрисовки DOM, то это позволяет предотвратить запуск скриптов сайта, а далее на страницу уже можно спокойно залить свое содержимое.
    Ответ написан
    Комментировать
  • Как сверстать такую секцию и как поступить с контейнером?

    @nikita1711
    Лучше будет разделить на левый и правый блоки, поставить им ширину по 60% и 40% примерно, а эти блоки уже поместить в контейнер.
    Ответ написан
    6 комментариев
  • Как сделать такой div блок без использования картинок?

    @Esal
    как вариант - использовать clip-path
    вот есть такой генератор https://bennettfeely.com/clippy/
    Ответ написан
    Комментировать
  • Как сделать мигающее уведомление во вкладке браузера?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, это два разных вопроса.
    По поводу мигания вам уже написали.
    А вот по поводу получения уведомления есть разные способы, все они потребуют фоновых запросов, чтобы не блокировать вкладку.
    Простейший пример - polling. Каждые несколько секунд шлем запрос на сервер "а есть ли новые сообщения?", на что сервер отвечает либо "нету" либо отдаёт список новых сообщений. Просто, но грузит сеть, жрёт батарейку, грузит сервер.
    Чуть сложнее - long polling. Мы шлём запрос "есть ли новые сообщения?" на сервер с длинным таймаутом, скажем, несколько минут. Если сообщений нет, сервер молчит, но запрос не прерывает. Он только у себя время от времени проверяет их наличие. Как только сообщение появилось, сервер шлёт ответ и закрывает соединение.
    Когда клиент получил ответ или когда случился таймаут, клиент запускает новое соединение и снова ждёт ответа.
    Ну или использовать web sockets - ЕМНИП, когда соединение установлено, сервер может уже послать что-то по своей инициативе. Но это нужно изучать.
    Ответ написан
    1 комментарий
  • Как сделать мигающее уведомление во вкладке браузера?

    https://developer.mozilla.org/en-US/docs/Web/API/D...
    https://developer.mozilla.org/en-US/docs/Mozilla/A...
    https://developer.mozilla.org/en-US/docs/Web/API/C...
    https://developer.mozilla.org/en-US/docs/Web/API/n...

    Это все касается интерактивной части уведомлений, а как получать уведомления с сервера вам уже описали.
    Ответ написан
    Комментировать