Функции, мультипарадигменный JS, модульность, разработка компонентов, шаблонизация

Технопарк, осень, 2024 г.

Функции, мультипарадигменный 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

		(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'" />
		 
	

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

Практика

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

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