• На собеседовании сказали, что не все функции - замыкания. Так ли это?

    @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 комментариев
  • Как оптимизировать фото на сайте?

    Сконвертировать их в WEBP, и также подключить CDN.

    17 мегабайт очень много
    61e5c06add86a486002945.png
    Ответ написан
    2 комментария
  • На каком CMS лучше делать проекты?

    WP конечно, чего тут думать.

    От CMS для небольших и средних проектов требуется имхо только одно - популярность.
    Чтобы потом не искать каких-то модулей типы webp, yml, seo и т.п. Больше готовых решений. Больше шаблонов. Больше ответов на форумах, больше специалистов, значит дешевле доработки и т.п.

    Поэтому просто смотрите что там нынче популярно: https://itrack.ru/research/cmsrate/
    WP = 43% от всех сайтов, Joomla = 9%
    Думаю, что всё понятно?

    Не лишним будет посмотреть и динамику развития популярности CMS за период, чтобы понять куда ветер дует.
    С 2013 года WP стабильно растет, Joomla стабильно падает - https://itrack.ru/research/cmsrate/dynamic/11/60/
    Можно сказать что WP растет за счет Joomla ))) сам раньше работал с joomla, пока не перешел на WP, еще ни разу не пожалел.
    Ответ написан
    2 комментария
  • Не получается создать шорткод?

    artzolin
    @artzolin Куратор тега WordPress
    php, WordPress разработка сайтов artzolin.ru
    Функция шорткода должна возвращать переменную return, а не выводить echo как у вас сейчас работает. Это можно сделать двумя способами

    1. Объявить буфер вывода ob_start() и вернуть его с помощью ob_get_contents()

    function slider_shortcode_func( $atts ) { 
    	ob_start(); ?>
    	
    	<div class="slider">
    		<div class="slider-init">
    			<h2>Slider Content</h2>
    		</div>
    	</div>
    
    	<?php ob_get_contents();
    }
    add_shortcode( 'slider', 'slider_shortcode_func' );


    2. Собрать и вернуть переменную с помощью конкатенации строк

    function slider_shortcode_func( $atts ) { 
    
    	$html = '';
    
    	$html .= '<div class="slider">';
    		$html .= '<div class="slider-init">';
    			$html .= '<h2>Slider Content</h2>';
    		$html .= '</div>';
    	$html .= '</div>';
    
    	return $html;
    }
    add_shortcode( 'slider', 'slider_shortcode_func' );


    В этом случае функции the_field() нужно переписать в get_field()

    PS. Раз передаете в них ID $slider_post->ID, функция setup_postdata() не нужна

    PSS. Разумеется функция getSlider() должна возвращаться массив записей для работы, без нее ничего работать не будет
    Ответ написан
    Комментировать
  • Toggle Class как написать на чистом javascript?

    groog
    @groog
    Я только учусь
    element.classList.toggle()
    https://developer.mozilla.org/en-US/docs/Web/API/E...

    Вот вам даже пример:
    Ссылка

    Пример использования
    const container = document.querySelector(".container");
    
    container.onclick = function(){
    	container.classList.toggle("container_color_red");
    }
    Ответ написан
    3 комментария
  • Какой плагин для Lazyload вы используете?

    alex_shevch
    @alex_shevch Автор вопроса
    Frontend Developer
    Спустя два года сам отвечу на свой вопрос – не нужны никакие плагины.
    На мой взгляд, лучшее решение – это использовать атрибут loading="lazy" на тегах img.
    Мало того, что это внедряется мгновенно и не требует доп библиотек, так ещё мы не просто тупо подгружаем изображения по ходу скролла, а перекладываем это на плечи браузера, который сам решает, в какой момент ему было бы оптимальнее его загрузить.

    Браузерная поддержка неплохая - https://caniuse.com/#feat=loading-lazy-attr
    Ответ написан
    5 комментариев
  • Для каких сайтов лучше всего использовать InnoDB?

    maxxannik
    @maxxannik
    Сайты на WordPress + Интернет магазины WooCommerce
    По умолчанию InnoDB.
    Когда будет сайт на 100 Гб БД, тогда есть смысл выбирать движки.
    Но таких сайтов на весь мир 3-4 штуки. Дорасти до такого шансов мало.
    Дорастете - у вас будет уже 10-20 своих программистов, которые решат этот вопрос на раз два.
    Ответ написан
    1 комментарий
  • Заблокировали на Upwork. Как быть?

    @Stalinko
    PHP'шник и фрилансер до мозга костей
    Ничего не бывает просто так и не бывает банов без объяснения причин.
    Что вы видите, когда заходите на сайт?
    Пробуйте связаться с техподдержкой. Добивайтесь выяснения причин.
    Ответ написан
    6 комментариев
  • Есть ли смысл распространять свою cms на php платно?

    @karminski
    Senior React.JS Developer
    У вас есть поддержка продукта в режиме 24/7? Вы юридическое лицо? Вам можно дозвониться по телефону в течении 15 мин? Если нет - забудьте про платную подписку.

    Какую юридическую ответственность вы готовы нести в случае простоев работы сайта клиента по причине ошибок в вашем коде?

    Сможете ли вы гарантированно исправить код проекта в течении суток с возникновения ошибки? Сможете ли вы оперативно (в течении 2,3 дней) закрывать бреши безопасности, которые находят постоянно в языке, который вы используете?

    Если вы одинокий разработчик и ваша система действительно хороша, в чем я, простите, но сомневаюсь, вам лучше продать проект инвестору.
    Ответ написан
    2 комментария
  • Как копируют калькуляторы с чужих сайтов?

    Zoominger
    @Zoominger
    System Integrator
    Уверен что никто не покупает и не пишет с нуля это

    Вы ошибаетесь.

    Мне нужен только "движок" калькулятора рабочий,

    Что это?

    Пишите сами, это нетрудно.
    Ответ написан
    2 комментария
  • Как копируют калькуляторы с чужих сайтов?

    Ответ написан
    Комментировать
  • Как сейчас дела у frontend разработчика на Upwork?

    @VegasChickiChicki
    У меня дед 50 лет назад работал кучером, заказов было - тьма, а сейчас печально как то все... Почему то кучеры не особо нужны( Везде одни водители автомобилей(((

    UPD
    А если серьезно. По моему, вы не понимаете как работает текущий рынок. Встаньте на место заказчика, кому сейчас нужна верстка? Ответ - почти не кому. Разве что студиям, которые делают какой нибудь проект и их верстальщик не справляется\не успевает, то да, вас возьмут на пару страниц. Сейчас всем нужны полноценные фронтэнд разработчики, которые и в JS могу и с беком связаться.

    Сейчас уже далеко не 2010 год, когда сайт состоял и одной верстки и отправки письма с заявкой на почту. Сейчас тонна всего что нужно знать.
    Ответ написан
    1 комментарий
  • Как правильно скрыть сайт от ПС во время наполнения?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    - В robots.txt запрещаем индексацию
    - Добавляем в шапку noindex
    - Отключаем карту сайта
    - Закрываем доступ для неавторизованных посетителей, чтобы только админы и редактора могли ходить по сайту, для всех остальных одна страница-заглушка "coming soon"
    - Когда сайт готов к публикации - открываем карту сайта, разрешаем индексирование, подключаемся к Google / Yandex Webmaster Tools, сабмиттим сайт в очередь на индексацию.
    Ответ написан
    Комментировать
  • Стоит ли использовать pug(jade)?

    @beduin01
    Я в свое время от него отказался т.к. подходы к верстке изменились и pug стал лишь усложнять, а не упрощать жизнь.
    Ответ написан
    4 комментария
  • Стоит ли использовать pug(jade)?

    Sanes
    @Sanes
    Чем разметка HTML не устраивает? Она и читабельней и редакторы с ней адекватно работают.
    Ответ написан
    2 комментария
  • Как называется или как сделать такой эффект?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Они используют CSS-градиенты и свойство backgrond-clip:
    5d6fafa56ad05473523050.png
    А перемещают эти градиенты нехитрой анимацией:
    5d6fb22c255d7506444602.png
    Также это можно делать на SVG-масках. Будет более кроссбраузерно.
    Ну и на канвасе можно, по тому же принципу, что и с масками.
    Ответ написан
    4 комментария
  • Сколько стоит час веб-разработчика-фрилансера?

    @deliro
    Ты веcь такой кругом молодец, то знаешь, это знаешь. А теперь представь себе среднестатистический проект, который должен приносить бизнесу деньги. За две недели работы ты едва напишешь хлипкий CRUD для данных, неправильно смаппив бизнес-сущности в объекты ORM, ещё через месяц натянешь какой-то слайдер на jQ, попутно захватив 2мб JS кривых библиотек, а через два заказчик поставит тебе плохую оценку, потому что твой ценник он оплатил не за то, что ему нужно, а потому что ты знаешь монады, которые ему даром не сдались.

    А теперь давай представим простого программиста. Из алгоритмов он с трудом вспоминает сортировку пузырьком, а двусвязный список — предел его знаний о структурах данных, и даже этим списком он пользовался два раза в жизни. Хаскель он никогда не видел в глаза, C++ учил только в школе, вместо этого пишет неэффективный код на PHP. И у него есть опыт. За день он распишет сущности, за второй сделает универсальный CRUD, на третий день поднимет фронт на React'е с SSR. Да, внутренности проекта будут "медленными". Вместо O(logN) что-то будет выполняться за O(N) или даже O(N^2), но всем похер. Пока всё работает на приемлемом уровне — бизнес радуется.

    Кстати, к чему эта поучительная лапша? Я хотел сказать, что всеми этими модными словами можно пугать друзей и преподавателей, но в реальной жизни все алгоритмы уже реализованы, все типы данных уже подобраны оптимально. Знать их полезно для себя (чтобы мозг не атрофировался), но не для работы. Для работы тебе нужны такие навыки как:

    * Оптимальный баланс между говнокодом и идеальным кодом
    * Оптимальный баланс между скоростью разработки и оптимизацией кода
    * Оптимальный баланс между поддерживаемым кодом и костылями
    * Умение использовать те инструменты, с которыми ты работаешь. Опять же, для того, чтобы писать быстро, при этом имея минимальное количество говнокода и обеспечивая максимальную поддерживаемость (в пределах сроков). Например, можешь выкинуть в помойку свой Vim, как бы круто ты себя не чувствовал, разрабатывая в консольном редакторе, если продукты от JetBrains позволят за это же время сделать что-то лучше или чего-то больше
    * Чувство "знаю больше менеджеров". Это то чувство, когда тебе кажется, что "вот эта фича скоро изменится" и надо сделать архитектуру заранее более гибкой. Или "вот эту фичу мы через месяц выпилим" и не надо тратить на неё силы — напиши костыль и через месяц с чистой совестью удали его
    * Знания, как сделать ту или иную фичу. Потому что фичи повторяются (немного видоизменяясь) от проекта к проекту. И если ты сделал что-то за два дня, в следующий раз ты похожее сделаешь за три часа

    Что касается инструментов, выбери любой полноценный фреймворк, который умеет решать 90%+ потребностей "из коробки": Symfony, Django, Laravel

    Всякие "минималистичные" поделия вроде Falcon, Flask (в PHP не знаю, я на питоне пишу) оставь хипстерам. Пусть они говорят: "Мой фалкон такой быстрый, он написан на Cython". Тебя это не должно волновать, потому что бизнес с твоей скоростью разработки уже заработал достаточно денег, чтобы купить ещё десять серверов, пока фалконисты неделю гуглили, как прикрутить миграциии и запустить юнит-тесты на VPSке за пять баксов.
    Ответ написан
    5 комментариев
  • Правда ли что рынок веб разработки "перегрет"?

    OTCloud
    @OTCloud
    Программирование и Архитектура ПО
    100% перегрет, но не программистами или веб-мастерами, а индивидами, которые решили что веб это просто и легко и не стоит сильно париться над своими скиллами и знаниями.
    Ответ написан
    8 комментариев
  • Как верстать под wp?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Верстка под WP по сути укладывается всего в несколько отличий от верстки под что либо еще:

    1. В некоторых местах (body, меню, обертки страниц/записей и тд) WP генерит свой список классов. Его можно и нужно использовать, если тема предназначена на продажу или в репозиторий на .org, предполагается что ее будут крутить/развивать под свои задачи. Если для себя / для клиента, то можно не использовать, но как минимум с меню придется на бекенде несколько правок сделать.
    2. Контент, который редактируется в редакторе (старый TinyMCE или новый Gutengerg) либо лишен классов по умолчанию (тогда стучимся по классу контейнера), либо как разработчики намудрят (Gutenberg, всякие конструкторы страниц). В принципе, можно полностью под себя сделать с Gutenberg, но это дополнительные временные расходы.
    3. Статика (скрипты, стили) подключается из PHP, картинки и другие файлы - как правило тоже, через медиа-библиотеку.

    Иногда что-то по мелочи попадается, но в целом - это все.
    Ответ написан