Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Спливання та перехоплення дозволяють нам реалізувати один з найпотужніших шаблонів обробки подій під назвою делегування подій.Ідея в тому, що якщо у нас є багато елементів, які обробляються подібним чином, то замість того, щоб призначати обробник кожному з них, ми ставимо один обробник на їхнього спільного предка. У обробнику ми отримуємо event.target, щоб побачити, де насправді сталася подія та обробити її.
this — посилання на об'єкт в контексті якого виконується функція. Іншими словами, якщо всередині функції є звернення типу this.им'я_властивості це означає, що ми звертаємося до властивості об'екту в контексті котрого ця функція виконується. Цей механізм дозволяє писати функції, які легко перевикористувати у подальшому.
Тут функція getName нічого не знає про об'єкт, в контексті якого вона буде викликана, проте чудово виконала свою роботу. Важливий момент: контекст виконання прив'язується в момент виклику функції (рядок getName.call(billy)). В ES6 була додана стрілкова функція, контекст виконання якої встановлюється не в момент виклику функції(як в прикладі, наведенному вище), а в момент виконання самої функції.
В плані наслідування JavaScript працює лише з однією сутністю: об'єктами. Кожен об'єкт має внутрішнє посилання на інший об'єкт, званий його прототипом. У об'єкта-прототипа також є свій власний прототип и так далі до тих пір, доки цепочка не завершиться об'єктом, у якого властивість prototype дорівнює null. По визначенню, null не має прототипів і є завершальною ланкою в ланцюжку прототипів. При спробі отримати доступ до будь-якої властивості об'єкта, властивість спочатку шукається в самому об'єкті, після цього в ланцюжку прототипів. Пошук ведеться до тих пір, доки не знайдено властивість з іменем, що збігається або доки кінець ланцюжка прототипів не буде досягнуто.
null — пусте значення, undefined — невизначене значення, undeclared — змінна не була оголошенаа, її виклик викличе помилку, виклик typeof покаже undefined (для реалізації перевірки). Для тестової змінної «a», перевірка може бути реалізована наступним чином: typeof a !== 'undefined' && Boolean(a)
Замикання - прийом, при якому функція має доступ до лексичної області видимості своєї функції-обгортки, яка була виконана раніше, але не може бути звільнена з пам'яті через те, що її власна область видимості ще використовується іншою функцією. Краще за все це проілюструє даний приклад:
function counterFn() { // функція-обгортка
var count = 0; // змінна в області видимості функції обгортки
return function() { // функція, яка буде використовуватись у подальшому
return ++count; // посилання на змінну з області видимості функції-обгортки
}
}
const counter = counterFn(); // функція-обгортка виконана
console.log(counter()); // 1 використовуємо вкладену функцію
// стан лічильника зберігається між викликами, оскільки воно зберігається в області видимості виконаної функції-обгортки
console.log(counter()); // 2
console.log(counter()); // 3
Для перебору всіх (власних та успадкованих) властивостей об'єкта використовується цикл for..in. Для простого перебору елементів массиву частіше за все використовується функція Array.forEach()
Метод Array.forEach() перебирає всі элементи массива і для кожного викликає передану в forEach callback функцію. Після відпрацювання нічого не повертає, при зміні элемента массива в callback функції зміни відображуються в вихідному масиві. Array.map() перебирає всі элементи массиву і для кожного викликає передану в forEach callback функцію. Після відпрацювання повертає новий массив, рівний по довжині вихідному, який містить в собі перетворені элементи массиву. При зміні элемента массива в callback функції зміни не відображуються у вихідому массиві.
Анонімними називаются функції, які не мають власного імені, як наслідок, їх не можна спочатку оголосити, а потімм викликати. Найчастіше такі функції використовують в якості callback функцій.
Native objects — об'єкти, визначені спецификацією ECMAScript, наприклад, Object (constructor), Date, Math. Host objects — об'єкти, чия роль полягає у створенні середовища виконання для ECMAScript, наприклад, window, document, location, history.
Function Declaration (функція, оголошена у потоці коду) — классична форма оголошення функції.
function sum(a, b) {
return a + b;
}
Function Expression (функціональний вираз) — альтернативний синтаксис для оголошення функції.
var sum = function(a, b) {
return a + b;
}
По суті, вони роблять те саме, але функції, оголошені як Function Declaration можуть бути викликані раніше, ніж були оголошені у коді (hoisting), а Function Expression ні.
sum(2, 4);
function sum(a, b) {
return a + b;
}
Обидва методи використовуються для вказання контексту, при виклику функції, до якої застосовується. Відрізняються синтаксисом, apply більш гнучка.
Function.prototype.bind — створює нову функцію, яка при виклику встановлює як контекст виконання (this) надане значення, тобто відповідає за виклик функцій з іншим контекстом.
Feature detection, feature inference та User Agent String – це практики визначення, чи існує певна функція web-технології у браузері.
Feature detection – це спосіб визначити, чи існує функція у певних браузерах.
Feature inference - припущення: якщо одна функція присутня (або ні), відповідно інша теж буде (або ні).
User Agent String - це текстовий рядок, який відправляє кожен браузер і до якого можна отримати доступ через navigator.userAgent. Цей рядок містить у собі інформацію про виконавче оточення.
Під час компіляції коду, оголошення деяких змінних і функцій підіймаються вище за інший код у межах своєї області видимості. Цей процес і називається hoisting. Завдяки чому функція буде успішно викликана не зважаючи на те, що в коді її виклик може йти перед оголошенням.
Сплив і занурення - це фази життєвого циклу події. Різниця полягає у моменті визначення факту настання події. Спочатку, при взаємодії користувача з елементом інтерфейсу (клік на кнопку, наприклад) подія занурюється від об'єкта window до цільового елементу (target), потім настає стадія спливання і подія спливає від target назад до window. Так, одна й та сама подія може бути перехоплена раніше чи пізніше.
Плюсом цього підходу є розширення базового функціоналу об'єкта. Прийом може бути застосований для визначення поліфілів. В цілому, розширення поведінки вбудованих об'єктів не вітається і є поганою практикою (monkey patching). Це порушує принцип інкапсуляції та засмічує базові об'єкти незадокументованою функціональністю.
Обидва оператори порівняння перевіряють тотожність. Відмінність полягає в тому, що подвійне дорівнює при порівнянні значень неявно наводить (перетворює) типи значень до єдиного, так рядок "1" і цифра 1 за такого порівняння будуть рівні. Потрійне дорівнює не виконує жодних неявних трансформацій, а отже вихідні типи матимуть значення. Таким чином рядок не буде дорівнювати числу і не важливо, що в обох операндах фігурує одиниця.
Same-origin policy (політика однакового джерела) - визначає як сайт (документ/скрипт), завантажений з одного джерела, може взаємодіяти в браузері з ресурсом (файлом, скриптом, об'єктом), з іншого джерела. Приклад: Якщо скрипт нашого сайту робить простий запит (GET) до чужого сервера й отримує у відповідь файл, при цьому у відповіді відсутній заголовок Access-Control-Allow-Origin або у значенні цього заголовка відсутній наш домен, браузер заборонить доступ до цього файлу (не дасть переглянути вміст відповіді) зі скриптів нашого сайту.
Тернарний оператор - це умовний оператор, що має форму запису: умова ? істинний вираз : хибний вираз. Тернарним його називають тому, що він має три операнди.
Strict (суворий режим) — особливий режим роботи компілятора, що включає нові можливості та деякі поліпшення обумовлені стандартом ECMAScript 5, при якому змінюється поведінка деяких функцій. Вмикається директивою use strict. Більшість сучасних браузерів підтримують strict режим, однак в деяких не повністю. Також не варто забувати про старіші версії (IE нижче версії 10). Суворий режим змінює семантику, що призводить до похибок та помилок. Потрібно підходити дуже уважно до використання суворого режиму та проводити тести для перевірки працездатності коду як у браузерах, які підтримують суворий режим, так і тих, що не підтримують.
TypeScript - одна з мов, яка дозволяє писати код, що компілюється в JS.
Серед його переваг варто зазначити:
Підтримка популярних IDE: Sublime Text, Visual Studio Code, WebStorm, Eclipse.
Реалізує багато принципів ООП: модифікатори доступу, успадкування, інкапсуляцію та поліморфізм.
Дозволяє швидше та простіше писати складні рішення, які легше тестувати та розвивати завдяки підтримці ООП та суворій типізації.
Існує система для роботи з модулями, класами. Навіть є можливість створювати абстрактні класи.
TypeScript назад сумісний із JavaScript. Будь-який код, написаний на JS буде виконано. Також можна писати змішаний код і він буде валідним.
Недоліки:
Наявність додаткових файлів (*.ts, *.d.ts, *.map), що є незручним для невеликих проектів.
Для деяких браузерів потрібне додаткове налаштування консолі для налагодження TypeScript.
TypeScript - мова з неявною статичною типізацією: тип може бути описаний як any, що відключить приведення до цього типу змінної.
d.ts декларації не завжди відповідають поточній версії бібліотеки.
У цілому нині — TypeScript відмінний вибір великих проектів, оскільки написання займає більше часу через описи декларацій класів і методів. Без статичної типізації в JavaScript, TypeScript — відмінне рішення.
Immutable об'єкт - незмінний. Об'єкт, стан якого не може бути змінено після створення. Відповідно, mutable об'єкт може бути змінений після створення. Усі примітиви (числа, рядки, булеві значення тощо) є імутабельними.
Переваги незмінності:
Просте та швидке відстеження змін (наприклад, не потрібно окремо порівнювати значення кожного поля вкладеного об'єкта. Можна просто порівняти посилання на об'єкти та відсіяти вкладені гілки порівнянь).
Більш безпечне використання та тестування.
Недоліки:
Створення нового об'єкта за кожної зміни може стати ресурсно-затратною операцією.
Використання методу Object.freeze() запобігає зміні об'єкта: додавання, видалення або зміна властивостей. Використання ключового слова const замість var або let не робить константу незмінною, проте запобігає повторному присвоюванню нового значення.
Синхронні функції - виконуються в порядку, в якому вони написані в тексті, по черзі.
Асинхронні функції - виконуються відкладено, потрапляючи перед виконанням у чергу, що дозволяє виконати їх, не блокуючи основний потік.
Task queue - черга із завершених асинхронних завдань, готових до синхронної обробки. З цієї черги завдання будуть поступово переміщені до call stack.
Call Stack — стек викликів за яким можна визначити, в якому місці програми зараз йде її обробка. Якщо стек не порожній, це означає виконання синхронних завдань, а саме, функції, яка знаходиться на верхівці стека.
Event loop — механізм, що переміщує готові до синхронної обробки асинхронні завдання з task queue в call stack.
const — змінним, оголошеним цим оператором, має бути одразу надано значення. Надалі значення може бути перевизначено. Змінна, оголошена в такий спосіб, не буде видно за межами блокової області видимості.
let — значення змінної, оголошеної цим оператором, може бути встановлене пізніше, а також може бути перевизначено в майбутньому. Змінну, оголошену в такий спосіб, не буде видно за межами блокової області видимості. Не доступний hoisting. Не підтримує повторне оголошення.
var — значення змінної, оголошеної цим оператором, може бути встановлене пізніше, а так само може бути перевизначене в майбутньому. Змінна, оголошена у такий спосіб, видно за межами блокової області видимості. Доступний hoisting. Підтримує повторне оголошення.
Методи класу є неперелічуваними властивостями; Код усередині класу за замовчуванням обробляється у строгому режимі; Є розбіжності у синтаксисі;
Стрілкові функції оголошуються особливою комбінацією символів () => {}. Мабуть, найбільш доречним варіантом застосування стрілкової функції є застосування її як callback функції. Це пояснюється основною відмінністю її від інших типів функцій - контекст виконання стрілкових функцій визначається не в момент виклику, а в момент оголошення (лексичний this).
Функція вищого порядку - функція яка приймає як аргумент іншу функцію або повертає функцію, тобто працює з іншими функціями. Array.prototype.reduce, Array.prototype.map та Array.prototype.filter – це функції вищого порядку.
Destructuring assignment - механізм вилучення даних з масивів та об'єктів. При цьому використовуються літерали масиву або об'єкта (залежно від того, що розуміємо), що збільшує читабельність і дозволяє відразу сказати об'єкт якого типу деструктурується. Наприклад:
var [firstItem] = arr;
По квадратних дужках відразу видно, що arr це масив
Шаблонний рядок - рядковий літерал, що дозволяє використовувати вирази всередині рядка. Оголошується косими лапками.
const variable = 'World!'
console.log(`Hello ${variable}`);
Каррування (currying) - перетворення функцій з безліччю аргументів на набір вкладених функцій з одним аргументом. Після виклику такої функції з передачею їй аргументу, вона повертає нову функцію, яка чекає на наступний аргумент і так до отримання результату.
Spread — оператор, що складається з трьох точок. Перевага – у короткій формі запису. Відмінність — залежно від місця застосування цей оператор сприймається як spread чи rest оператор. Rest використовується для деструктуризації колекцій (поділ на окремі елементи), а spread, навпаки, для з'єднання окремих значень масиву.
let arr = ['one', 'two', 'three', 'four'];
// деструктуризація трьома точками (rest)
let [first, second, ...rest] = arr;
console.log(first); // 'one'
console.log(second); // 'two'
console.log(rest); // ['three', 'four']
// об'єднання трьома точками. Схожий синтаксис, але поведінка інша
const restored = [first, second, ...rest];
console.log(restored) //['one', 'two', 'three', 'four'];