• Как работает замыкание в js?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    function createCounter() { 
        let counter =0; 
       counter = counter - 10  
        const myFunction = function () { 
            counter = counter+1; 
            return counter 
        } 
        return myFunction 
    } 
    let z = createCounter() // Вернули в переменную z функцию "myFunction" у которой в замыкании есть counter.
    // counter внутри на данный момент равен -10.
    
    // Вызвали функцию и вывели результат в консоль.
    // Так как внутри функции counter берётся из замыкания, то при вызове функции получаем
    // -10 + 1
    console.log(z()) // -9
    
    // В данном примере - бесполезный ничего не делающий вызов.
    // То есть создаётся ещё один НОВЫЙ счётчик, со своим замыканием, но он никуда не сохраняется.
    createCounter() 
    
    // Снова вызвали функцию и вывели результат в консоль.
    // -9 + 1 
    console.log(z()) //  -8


    где я допускаю ошибку

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

    Второй вопрос откуда берется counter при втором вызове console.log(z())

    Да всё оттуда же. Из замыкания. Когда Вы в первый раз вызвали функцию createCounter и сохранили результат её работы в переменную z - Вы в переменную z поместили функцию myFunction, у которой есть своё собственное замыкание на counter.
    При каждом вызове z() будет вызываться та созданная функция со своим замыканием и оперировать с counter из него.

    При новом вызове createCounter возвращается НОВАЯ функция myFunction у которой своё независимое от предыдущих вызовов замыкание.
    То есть createFunction это как фабрика, которая выпускает одинаковые изделия(счётчики от -10, в данном случае), но изделия не зависят друг от друга.
    Ответ написан
  • Как сделать рамку в виде продолжения цифры?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Самый простой и логичный вариант: конвертировать цифры в заданном шрифте в SVG в нужном стиле с заданным фоном в самой цифре. Далее делаем рамку контейнеру с контентом, при этом цифру просто смещаем на толщину линии относительно нужной границы, чтобы часть рамки цифры выходила за границу родительского контейнера и была не видна.
    Ответ написан
    Комментировать
  • Почему не видит данные которые забили в input?

    victormayorov
    @victormayorov
    Frontend разработчик
    Проблема в том, что вы записываете значения с сессию с ключом texexperto, а пытаетесь вытащить с texex.
    Ничего с ключом texex не найдено и по этому возвращается null.

    <form style="position:relative" target="area" method="POST">	    
            <input id="texexpert" name="texe"class="header-search-input" autocomplete="off" placeholder="Искать"  value="" >
            <input id="button" class="texex" type="submit" title="Нажмите,чтобы найти">
      </form
    
    <script>
    $('.texex').on('click', function(e){
      e.preventDefault();
      const texex = document.querySelector("input[name='texe']").value;
      sessionStorage.setItem('texexperto', texex);
      const texoton = sessionStorage.getItem('texexperto');
      console.log(texoton);
     });
    </script>
    Ответ написан
    1 комментарий
  • Почему переменную не видно внутри iife?

    @historydev Куратор тега JavaScript
    Острая аллергия на анимешников
    Потому-что точки с запятой ставить нужно.
    const url = 'https://jsonplaceholder.typicode.com/todos/1';
    
    (async () => {
    	
    	console.log(url)
    })()
    Ответ написан
    Комментировать
  • Как быстро отбирать качественные видео на ютубе для реализации конкретных но совершенно новых задач?

    gbg
    @gbg
    Любые ответы на любые вопросы
    Ответ вроде уже на поверхности, но вы не желаете его видеть - не следует учиться по видео, если это не какой-то практический навык вроде разборки ноутбука

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

    Если вам проще воспринимать информацию на слух чем на глаз, подумайте над тем, а ту ли профессию вы выбрали.

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

    Далее

    Усилия на продакшн видео, как правило, превосходят те, которые нужны для того, чтобы подготовить текст.

    СЮРПРИЗ

    Для хорошего видео тоже нужен текст. Видео, записанное без подготовки и слайдов, это беее, меее, плохая структура и прочий шлак.

    Вывод - первичным источником информации всегда является текст.

    Учитесь по текстам.
    Ответ написан
    4 комментария
  • Почему выдает false?

    Lynn
    @Lynn
    nginx, js, css
    Kerrik Солнце, ну нельзя же настолько не знать (не понимать) язык…

    Вы обращаетесь к переменной constructor. Подозреваю что вы делаете это в консоли браузера и переменную эту никогда не объявляли, поэтому JS выдаст вам свойство constructor глобального объекта. В данном случае это будет window.constructor который конечно же никакого отношения к вашей функции Func не имеет.

    И в любом случае constructor имеет смысл смотреть у экземпляра объекта, а не у класса.

    let f = new Func();
    console.log(f.constructor === Func) // true

    Ответ написан
    Комментировать
  • Почему не выполняется код после await?

    groog
    @groog
    Я только учусь
    Вы в своем коде промис не резолвите. Вот он и ждет. У промисов нет автозавершения.

    Но если вам нужен эффект после css анимаций используйте события transitionend или animationend
    Ответ написан
    8 комментариев
  • Как выбрать элемент если у него нет id, но он находиться в теге option в select?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    По стандарту HTML в тэг option не могут вкладываться другие тэги.
    Content model:
    - If the element has a label attribute and a value attribute: Nothing.
    - If the element has a label attribute but no value attribute: Text.
    - If the element has no label attribute: and is not a child of a datalist element: Text that is not inter-element white space.
    - If the element has no label attribute and is a child of a datalist element: Text.

    https://www.w3.org/TR/html52/sec-forms.html#the-op...
    Ответ написан
    Комментировать
  • Как любое число подогнать под числовой диапазон на JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const mod = (a, b) => ((a % b) + b) % b;
    // или
    const mod = (a, b) => a - (b * Math.floor(a / b));
    
    
    console.log([ 12, 367, -54, 789, -567 ].map(n => mod(n, 360)));
    Ответ написан
    1 комментарий
  • Почему при выполнении скрипта node.js увеличивается занятая RAM?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Давайте посмотрим, что Вы тут накодили... Я уберу Ваши комментарии из кода и добавлю свои:
    const setup = {port:8000}
    const express = require ('express');
    const puppeteer = require('puppeteer');
    
    const app = express ();
    
    app.get('/', (req, res) => {
        const url = req.query.url;
    
        // вот тут Вы на каждый запрос создаете весьма тяжелую функцию
        // в ней 203 AST ноды
        // и она жрет в среднем 220КБ оперативы
        // (node: 14.4.0; v8: 8.1.307.31-node.33, мерил через process.memoryUsage().heapUsed)
        let scrape = async () => {
    
            // а еще на каждый запрос запускам новый браузер
            // у ноды это особо памяти не отнимет, а вот у системы - прилично
            const browser = await puppeteer.launch({args: ['--no-sandbox']});
            const page = await browser.newPage();
    
            // еще и разрешаем запросу из браузера жить вечно
            // если конечно сервак не оборвет коннект
            await page.setDefaultNavigationTimeout(0);
    
            await page.setUserAgent('Mozilla/5.0 (Linux; Android 7.0; NEM-L51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36');
            await page.setViewport({width: 375, height: 812});
    
            // куда мы отправляем браузер?
            // переменная url у нас из req.query.url - а следовательно начинается с /
            // то есть без хоста и протокола...
            await page.goto(url);
    
            // что-то мне подсказывает, что это работает не совсем так
            // как Вы ожидаете
            // https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pageevaluatepagefunction-args
            // читаем: If the function passed to the page.evaluate returns a non-Serializable value, then page.evaluate resolves to undefined
            const bottomSheet = await page.evaluate(() => {
                return document.querySelector('div[data-marker="bottom-sheet"]');
            });
    
            // так как undefined !== null данное условие всегда истинно
            if (bottomSheet !== null) {
                // здесь по идее придет Promise.reject который мы не ловим (об этом ниже)
                await page.click('div[data-marker="bottom-sheet"] button');
            }
    
            // и еще раз... ловите доку на нужный метод:
            // https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pageselector
            const phoneButton = await page.evaluate(() => {
                return document.querySelector('a[data-marker="item-contact-bar/call"]');
            });
    
            // всегда ложное условие...
            if (phoneButton === null) {
                await browser.close();
                return false; // ...с return внутри...
            }
    
            // еще 1 способ зависнуть (дефолтный таймаут 30 сек)
            await page.waitForSelector('a[data-marker="item-contact-bar/call"]');
    
            await page.click('a[data-marker="item-contact-bar/call"]');
    
            try {
                await page.waitForSelector('span[data-marker="phone-popup/phone-number"]');
            } catch (e) {
                await browser.close();
                return false;
            }
    
    
            const result = await page.evaluate(() => {
                console.log('phone', document.querySelector('span[data-marker="phone-popup/phone-number"]'));
                return document.querySelector('span[data-marker="phone-popup/phone-number"]').innerHTML;
    
            });
    
            await browser.close();
            return result;
    
        };
    
        // не ловим reject промиса
        // и в случае reject не завершаем запрос
        // и он тоже висит в памяти
        scrape().then((value) => {
            console.log(value);
            if (value === false)
                res.send(500);
            // при value === false будет запись в закрытый поток... (или у express есть защита от дурака?)
            res.send(value);
            // абсолютно бесполезное действие...
            scrape = null;
        });
    });
    
    
    app.get('/test', (req, res) => {
        res.send('Тест');
    });
    
    app.listen(setup.port, () => {
        console.log('Сервер: порт %s - старт!', setup.port);
    });
    Ответ написан
    1 комментарий
  • Форма на vue. Как правильно?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    data() {
        return {
          formData: {
            name: '',
            email: '',
            caps: ''
          },
          response: '',
          activeClass: 'active'
        }
      },

    submitForm() {
       axios.post('//jsonplaceholder.typicode.com/posts', this.formData)
    }
    Ну и, соответственно, v-model="formData.name" и т.п.
    Ответ написан
    2 комментария
  • Объясните как работает position: fixed; когда используется transform?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    кто может объяснить это поведение?

    Спецификация может объяснить:

    For elements whose layout is governed by the CSS box model, any value other than none for the transform also causes the element to become a containing block, and the object acts as a containing block for fixed positioned descendants.


    Добавили элементу transform - все его потомки с position:fixed начинают отсчитывать свое расположение от него. Они начинают считать его своим "внешним блоком", а не вьюпорт или страницу, как это происходит по умолчанию для position:fixed.
    Ответ написан
    3 комментария
  • Актуален ли Logux?

    Привет. Актуальна — проект развивается и задачи такие сейчас стоят часто. Недавно выпустили документацию и красивый сайт для проекта. Сами используем его в продакшене и знаю несколько проектов, который внедрили Логакс.

    На Логакс стоит смотреть если:

    1. У тебя на сайте несколько пользователей могут редактировать один документ — это очень часто в различных админках, где в компании несколько менеджеров. Тут конкурентов вообще мало, но и Логакс не даст 100% решения, надо будет грамотно продумывать атомарные операции. Хотя даже если не продумывать будет лучше, чем с AJAX/GraphQL.
    2. Если нужны обновления данных без перезагрузки страницы. Тут решений много, но Логакс отлично ложиться если у тебя Redux — не надо делать отдельный слой совместимости, просто пересылаешь экшены. Ну и всякие приятные мелочи есть — синхронизация между вкладками, корректное поведение в офлайн и т. п.
    3. Если нужен оптимистичный UI — когда форма закрывается сразу по нажатию на Сохранить. Это круто ускоряет UI, но, понятно, что просто ради одной-двух форм нет смысла добавлять Логакс. Это скорее как дополнительный бонус
    4. Если надоело как криво работают современные приложения с реальной сетью. Это было главной причиной создания Логакса для меня. Хочется, чтобы данные между вкладками синхронизировались. Чтобы приложение не показывало бесконечную критику, если Интернет пропал (а это происходит постоянно). В отличии от AJAX и GraphQL, Логакс сразу сделан из расчёта реального Интернета, а не идеальной связи localhost-localhost на машине разработчика.


    Конкуренты: для задачи 1 можно взять Firebase, но это vendor lock-in, сложно использовать свою базу и разрешение конфликтов чуть хуже. Для задачи 2 есть много решений (гугли по websocket js) в том числе для GraphQL — но у многих решений хуже продуманы крайние случаи (например, разный порядок событий на разных клиентах приведёт к разному результату). Для оптимистичного UI тоже есть решения, большинство их которых так же ломается в реальных случаях (что будет если сервер упал).

    Но вообще сейчас много есть попыток пересоздать связь с сервером — тот же gun.js. Гугли по CRDT js.

    Вопросы можно задать нам в гитер-чате.
    Ответ написан
    Комментировать
  • Что это за сортировка (JS)?

    longclaps
    @longclaps
    не особо разобравшись в ее теории
    Это звучит забавно.
    Да, это быстрая сортировка в её игрушечном варианте и даже чуть хуже (есть избыточная проверка).
    Неигрушечный вариант экономней по памяти, но требует аккуратной работы с индексами.
    Ответ написан
  • Почему во vue.js интерполяция не отображает значение?

    @AndrewRusinas
    Потому, что выходит за область видимости цикла v-for. Там нет переменной perfume) Переменная perfume доступна только внутри тега <li>, к которому применена директива v-for. При чем на любом уровне вложенности внутри , но не вне.
    Ответ написан
    Комментировать
  • Как перевести jQuery в чистый JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    А что, сделать один запрос вместо отдельных для каждого элемента - нет, было никак? Свойство Documents, оно же массив, можно сразу всё передать.

    document.querySelector('.allstatus-btn').addEventListener('click', () => {
      const items = Object.fromEntries(Array.from(
        document.querySelectorAll('.number-all'),
        n => [ n.innerText, n ]
      ));
    
      fetch('https://api.novaposhta.ua/v2.0/json/', {
        method: 'POST',
        body: JSON.stringify({
          modelName: 'TrackingDocument',
          calledMethod: 'getStatusDocuments',
          methodProperties: {
            Documents: Object.keys(items).map(n => ({
              DocumentNumber: n,
              Phone: '',
            })),
          },
          apiKey: '',
        }),
      })
        .then(r => r.json())
        .then(r => r.data.forEach(n => items[n.Number].innerHTML += n.Status));
    });
    Ответ написан
    Комментировать
  • Почему не работают слоты в Nuxt.js?

    Machinez
    @Machinez
    нет такого синтаксиса v:slot:title, есть v-slot:title или сокращенно #title
    читайте документацию внимательней
    Ответ написан
    1 комментарий
  • Как во Vue игнорироть скобки, кавычки и тд в тексте?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Как и в обычном html, с помощью спец. символов
    Ответ написан
    Комментировать
  • Получение значений полей в php созданных через JS?

    @andreysuha
    Что то знаю
    ajax с фронта отправляешь на сервере ловишь и используешь.
    Ответ написан
    7 комментариев