## Функции, мультипарадигменный JS, модульность, разработка компонентов, шаблонизация
Слайды доступны по ссылке
frontend.tech-mail.ru

## Немного философии

## Что такое функция?

> Фу́нкция (лат. functio — «исполнение, совершение; служебная обязанность») — отношение между элементами, при котором изменение в одном элементе влечёт изменение в другом

- Математика – отображение или преобразование элементов одного множества в элементы другого множества
- Программирование – ссылка на блок операторов (не обязательно именованный), реализующий последовательность действий

## Чистые (pure) функции

> Чистыми (pure) называются функции, не производящие побочных эффектов

Такая функция:
- Вычисляет результат только на основе аргументов
- Возвращает гарантированно детерминированный результат

Плюсы:
- Легче читать и понимать код
- Легче тестировать (не надо создавать «условий»)
- Надежнее, потому что не зависят от «погоды» и состояния окружения, только от аргументов
- Можно запускать параллельно, можно кешировать результат и т.д. и т.п.

## Чистые (pure) функции

## Функции чистые, а мир вокруг...

> "Не надо быть гением, чтобы понять, что у мира есть проблемы." © фильм Хранители

Примеры побочных эффектов: печать, сетевой запрос, изменение состояния.
`Math.random`

Вывод – без фанатизма.

## Функции в JavaScript

## Примеры по ссылке

## Объекты первого класса

> Объектами первого класса (англ. first-class object, first-class entity, first-class citizen) в контексте конкретного языка программирования называются элементы, которые могут быть переданы как параметр, возвращены из функции, присвоены переменной.

Функции в JavaScript – объекты первого класса.
Это значит, что в JS можно создавать функции высшего порядка

## Котик

## 2 котика

## Замыкания!
или как работает JavaScript

## Лексическое окружение

Все переменные внутри функции — это свойства специального внутреннего объекта LexicalEnvironment , который создаётся при её запуске

    		function sayHello(name) {
    		    const magicNumber = 42;
    		    console.log(`Hello, ${name}`);
    		}

    		sayHello('Лаврентий');
    		// LexicalEnvironment = {name: 'Лаврентий', magicNumber: 42}

## Внешние переменные

    		var otherName = 'Ivan'; // window.otherName = Ivan

    		function sayHello(name) {
    		    let magicNumber = 42;
    		    console.log(`Hello, ${otherName}`);
    		}

    		sayHello('Лаврентий');
    		// LexicalEnvironment = {name: 'Лаврентий', magicNumber: 42}
    		// sayHello.[[Scope]] = window

## Ссылка на `стандарт`

## Демонстрация

## Замыкание

    		function sum(operand1) {
    		    return function(operand2) {
    		        console.log(operand1 + operand2);
    		    }
    		}

    		// const sum = a => b => a + b

    		let plus3 = sum(3);
    		plus3(6); // 9

## Замыкание

## Мультипарадигменный JavaScript

## Функциональный JS

## Примеры по ссылке

## Пёсик

## Много пёсиков

## ООП парадигма в JS

## Примеры по ссылке

## Что ещё?

Реактивное, событийно-ориентированное, агентно-ориентированное программирование и т.д.

## Модули

> Модуль — функционально законченный фрагмент программы, оформленный в виде отдельного файла с исходным кодом… предназначенный для использования в других программах

## Модули — будущее настоящее

- IIFE – Immediately Invoked Function Expression. Фактически просто замыкание
- AMD – Asynchronous Module Definition (Require.js)
- CommonJS – синхронный запрос модуля (Node.js)
- UMD – Universal Module Definition (и туда, и сюда)
- ESM – ECMAScript модули

## Модули IIFE

    		(function () {
    		    let importedModule = window.importedModule;

    		    class AwesomeClass {
    		        //...
    		    }

    		    window.exportedModule = AwesomeClass;
    		})();

## Модули AMD

    		define(['a', 'b'], (a, b) => {
    				...
    				//Определение модуля с помощью возвращаемого значения
    				return function () {};
    		})

## Модули UMD

    		(function (root, factory) {
    			if (typeof define === 'function' && define.amd) {
    				//AMD
    				define(['b'], factory);
    			} else if (typeof module === 'object' && module.exports) {
    				//CommonJS
    				module.exports = factory(require('b'));
    				//b – зависимость
    		})(this, function (b) {
    				//Код модуля
    				return {};
    		})

## Модули ES6 module

    		// main.js
    		import AwesomeClass from './package.js'
    		let awesome = new AwesomeClass();

    		// package.js
    		class AwesomeClass {
    		  //...
    		}

    		export default AwesomeClass;

## caniuse.com a while ago

## caniuse.com now

## Модульный подход к разработке

## Компоненты

## Практика

## Шаблонизация

## Создадим простой элемент

    		let data = {text: 'Текст элемента!'};
    		let block = document.createElement('div');
    		block.classList.add('block');

    		let blockEl = document.createElement('div');
    		blockEl.classList.add('block__el', 'block__el_mod');
    		blockEl.textContent = data.text

    		block.appendChild(blockEl);

## Можно поступить проще

    		let data = {text: 'Текст элемента!'};
    		let block = document.createElement('div');
    		block.innerHTML = `
    		    <div class="block">
    		        <div class="block__el block__el_mod">
    		           ${data.text}
    		        </div>
    		    </div>`;

    		block.appendChild(blockEl);

## Микрошаблоны

    		<div class="menu">
    		    <span class="title"><%-title%></span>
    		    <ul>
    		        <% items.forEach(function(item) { %>
    		            <li><%-item%></li>
    		        <% }); %>
    		    </ul>
    		</div>

## "Свой" язык

    		<fest:template xmlns:fest="http://fest.mail.ru"
    		    context_name="json">
    		    <div>
    		        <h1>Epic Game</h1>
    		    </div>
    		</fest:template>

## В результате — JavaScript-код

    		;(function(){var x=Function('return this')();if(!x.fest)x.fest={};
    		x.fest['fest']=function (__fest_context){"use strict";
    		var __fest_self=this,__fest_buf="",__fest_chunks=[],__fest_chunk,__fest_attrs=[]
    		,__fest_select,__fest_if,__fest_iterator,__fest_to,__fest_fn,__fest_html="",
    		__fest_blocks={},__fest_params,__fest_element,__fest_debug_file="",
    		__fest_debug_line="",__fest_debug_block="",__fest_htmlchars=/[&<>"]/g,
    		...
    		...
    		return __fest_html+__fest_buf;} else {return __fest_buf;}}})();

## Шаблонизация компонентов

    		<div class="block">
    		    <div data-bind="text: text" class="block__el block__el_mod">
    		        <!-- some code -->
    		    </div>
    		</div>
    		<input data-bind="value: name, valueUpdate: 'input'" />

## Сторонние решения

- Handlebars
- pug
- Nunjucks
- Underscore
- Hogan
- doT
- EJS
- Место для вашей библиотеки

## Практика

## Дополнительные материалы

- Подробнее про замыкания в JavaScript
- Подробнее про Модули js
- Подробнее про ES6 модули
- Подробнее про шаблонизацию
- react JSX
- Статический анализ JavaScript с использованием ESLint или JSHint

## Всем спасибо!