Javascript Base Flashcards
Характеристика языка Javascript
JavaScript - это динамически типизированный (одна переменная может принимать разные типы), встраиваемый язык, т.е. ему для работы нужно некоторое окружение (например, браузер(сайты) или платформа node.js(мобильные и десктопные приложения - вне браузера))
Как запустить Javascript-код
С помощью node.js:
node main.js
С помощью браузера:
добавить скрипт на страницу html
Почему JavaScript-код лучше выносить в отдельный файл?
- чтобы браузер мог закэшировать его и не запрашивать повторно
- принцип разделения ответственности
Типы данных Javascript
Примитивные:
- string
- number
- boolean
- symbol
- null
- undefined
- bigint (специальный
числовой тип, который
предоставляет
возможность работать с
целыми числами
произвольной длины)
Составные:
- Объекты
- массивы
Ввод данных в Javascript
Браузер:
let username = prompt(“Как вас зовут?”);
node.js:
const readline = require(‘readline’).createInterface({
input: process.stdin,
output: process.stdout
});
readline.question(‘Как вас зовут?’, name => {
console.log(name);
readline.close();
});
Область видимости переменной
Если переменная объявлена внутри блока кода {…}, то она видна только внутри этого блока
Лексическое окружение
В JavaScript у каждой выполняемой функции, блока кода{…}и скрипта есть связанный с ними внутренний (скрытый) объект, называемыйлексическим окружением LexicalEnvironment, состоящим из:
- Environment Record (объект, в котором в виде свойств хранятся все локальные переменные блоков)
- Ссылка на внешнее лексическое окружение (то, что вне блока)
Когда код хочет получить доступ к переменной – сначала происходит поиск во внутреннем лексическом окружении, затем во внешнем, затем в следующем и так далее, до глобального
Strict mode в JavaScript
— это специальный режим, который делает код более безопасным и помогает избежать распространённых ошибок:
- Запрещает использование устаревшего синтаксиса
- Превращает «тихие» ошибки в исключения
- запрещает использование глобальных переменных без объявления
Замыкание
Замыкание – это функция, которая запоминает свои внешние переменные и может получить к ним доступ.
- В Javascript все функции изначально являются замыканиями (функции «видят» и могут использовать переменные, которые были доступны во время её создания)
Массив в Javascript
Массив в JS - ссылочный составной тип данных, элементы которого могут быть разных типов:
const mixedArray = [1, “блаженство”, true, { key: “value” }, null];
Методы массива
- shift (Удаляет первый элемент из массива и возвращает его)
- unshift (Добавляет один или несколько элементов в начало массива)
- push (Добавляет один или несколько элементов в конец массива)
- pop (удаляет последний элемент из массива и возвращает его)
- slice (возвращает новый массив, содержащий выбранные элементы из исходного массива)
- concat (объединение двух или более массивов в один новый массив)
- split (для разделения строки на подстроки по символу и создания массива на основе этих подстрок)
- join (для объединения элементов массива в строку с помощью заданного разделителя)
- map (для создания нового массива путем применения функции к каждому элементу исходного массива)
- filter (создает новый массив, содержащий элементы, которые удовлетворяют условию)
- includes (для проверки наличия элемента в массиве)
Объект в Javascript
Объект - ссылочный составной тип данных, который позволяет объединить несколько значений и функций в одну сущность (Изменения в копии объекта повлияют на оригинальное значение объекта):
const person = {
name: “Вася”,
age: 97,
isStudent: true,
};
Объекты могут быть вложенными
Перебираемые объекты
это обобщение массивов, что позволяет использовать любой объект в циклеfor..of.
Чтобы сделать объект итерируемым, нужно добавить в него метод Symbol.iterator(), который должен вернуть итератор (объект с методом next(), который должен возвращать {done: Boolean, value: any}
Мутация объектов
- Добавление свойства:
const person = {};
person.occupation = “programmer” - Удаление свойства:
let person = {name: ‘Татьяна’};
delete person.name;
Методы объекта
это функции, которые связаны с определенным объектом:
let car = {
brand: “Toyota”,
model: “Camry”,
start: function() {
console.log(“Автомобиль заведен”);
},
//сокращенный синтаксис
stop() {
console.log(“Автомобиль заглушен”);
}
};
Ключевое слово «this»
Ключевое слово «this» - позволяет обращаться к свойствам и методам объекта, даже если имя объекта меняется или неизвестно заранее
Глобальный объект
Глобальный объект - предоставляет переменные и функции, доступные в любом месте программы:
- для браузера: window
- для node.js: global
setTimeout, setInterval
setTimeout - позволяет вызвать функцию один раз через определённый интервал времени:
- возвращает id таймера
- отмена выполнения: clearTimeout(timerId)
setInterval - позволяет вызывать функцию регулярно повторяя через определённый интервал времени
Стрелочная функция
Похожа на лямбда-выражение:
let greet = () => console.log(“Все понятно”);
- нет this
- нельзя использовать с оператором new
- не имеют переменной arguments
Функция в JavaScript
Функция - этофрагмент кода, к которому можно обратиться в любом месте программы.
Функция может быть динамически создана, скопирована в другую переменную или передана как аргумент другой функции и позже вызвана из совершенно другого места.
Все аргументы функции (не стрелочной) хранятся в псевдомассиве arguments
function greetUser() {
console.log(“Привет, пользователь”);
}
// Вызов функции
greetUser();
Вызывать функцию можно с любым количеством аргументов независимо от того, как она была определена
Функциональные выражения Function Expression
let greet = function(name) {
console.log(“Привет, “ + name + “!”);
};
Остаточные параметры функций
Вызывать функцию можно с любым количеством аргументов независимо от того, как она была определена, но чтобы их задействовать, нужно использовать остаточные параметры:
function sumAll(…args) { // args — имя массива
let sum = 0;
for (let arg of args) sum += arg;
return sum;
}
Оператор расширения
Оператор расширения “…” при передаче аргументов в фунцию, применяется для:
- преобразования массива в набор отдельных значений
- для слияния массивов
- чтобы превратить строку в массив символов
// return 5 (оператор “раскрывает” массив в список аргументов)
alert( Math.max(…arr) );
Объект функции
Функция в Javascript - это объект со свойствами:
- name (название функции или переменной, которой присваивается функция, создаваемая без имени)
- length (количество параметров, кроме …params)
- пользовательские свойства
Named Function Expression (NFE)
Named Function Expression (NFE) - это Function Expression, у которого задано имя:
- позволяет функции ссылаться на себя же по имени
- имя не доступно за пределами функции
let sayHi = function(who) {
alert(Hello, ${who}
);
};
Способы решения проблемы потери контекста (this)
Проблема потери контекста (this) - возникает, при передаче методов объекта в качестве колбэков.
Способы решения:
- Обернуть вызов в анонимную функцию, создав замыкание:
let user = {
firstName: “Вася”,
sayHi() {
alert(Привет, ${this.firstName}!
);
}
};
setTimeout(() => user.sayHi(), 1000);
- Привязать контекст с помощью bind:
let user = {
firstName: “Вася”,
sayHi() {
alert(Привет, ${this.firstName}!
);
}
};let sayHi = user.sayHi.bind(user);
sayHi(); // Привет, Вася!
Прототипы
Объекты в Javascript имеют специальное скрытое свойство [[Prototype]], которое либо равноnull, либо ссылается на другой объект (прототип):
let animal = {
eats: true,
walk() {
alert(“Animal walk”);
}
};
let rabbit = {
jumps: true,
//задание свойства прототип
__proto__: animal
};
// walk взят из прототипа
rabbit.walk(); // Animal walk
Современные методы установки прототипа
- Object.create(proto, descriptors) – создаёт пустой объект со свойством [[Prototype]], указанным как proto, и необязательными дескрипторами свойств descriptors.
- Object.getPrototypeOf(obj) – возвращает свойство [[Prototype]] объекта obj.
- Object.setPrototypeOf(obj, proto) – устанавливает свойство [[Prototype]] объекта obj как proto.
let animal = {
eats: true
};
// создаём новый объект с прототипом animal
let rabbit = Object.create(animal);
alert(rabbit.eats); // true
alert(Object.getPrototypeOf(rabbit) === animal); // получаем прототип объекта rabbit
Object.setPrototypeOf(rabbit, {}); // заменяем прототип объекта rabbit на {}
Ограничения прототипного наследования
1) Запрет циклических ссылок.
2) Значение\_\_proto\_\_
может быть объектом илиnull
(Другие типы игнорируются).
3) Прототип у объекта может быть только один.
4) Прототип используется только для чтения свойств, кроме свойств-аксессоров.
5) Можно переопределить метод в наследнике, но это не затронет родителя.
Иерархия наследования встроенных прототипов
- Корневой прототип
Object.prototype
с методами toString и др: - Его наследники:
- Array.prototype (slice, …)
- Function.prototype (call, …)
- Number.prototype (toFixed, …)
Управление памятью в Javascript
Управление памятью в JavaScript выполняется автоматически фоновым процессом (сборщиком мусора).
Сборка мусора происходит по принципу достижимости:
- Любое другое значение считается достижимым, если оно доступно из корня по ссылке или по цепочке ссылок
- Корни - это значения, которые в текущий момент времени используются:
- Глобальные переменные
- Выполняемая в данный момент функция, её локальные переменные и параметры
Если удалить корень, то все зависимые от него объекты будут уничтожены
Классы в Javascript
Класс в Javascript - это разновидность функции (а функция - это объект), его применяют в качестве современного способа создания множества объектов одного вида с помощью оператора new, классы всегда используют strict режим. Классы можно присваивать переменным
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
// Использование:
let user = new User(“Иван”);
user.sayHi();
//настоящий тип класса User - это функция
alert(typeof User); // function
//присваивание класса переменной
let User = class {
sayHi() {
alert(“Привет”);
}
};
Внутренние алгоритмы сборщика мусора
Алгоритм пометок:
- Сборщик мусора «помечает» (запоминает) все корневые объекты
- Затем он идёт по ним и «помечает» все ссылки из них
- Затем он идёт по отмеченным объектам и отмечает их ссылки.
- Все непомеченные объекты удаляются
Наследование классов
- для наследования исп. ключевое слово extends
- наследники имеют доступ к методам родителя
- наследники могут переопределять методы родителя
- можно наследовать не только классы, но и обычные функции
- если класс-наследник не имеет конструктора, то автоматически создаётся конструктор, вызывающий конструктор родителя
- конструкторы наследников обязательно должны вызывать конструктор родителя перед установкой своих свойств
- Ключевое слово super основано не на прототипе, а на спец. внутреннем свойстве [[HomeObject]]
- В Javascript можно наследоваться только от одного класса.
Статические свойства и методы классов
- исп. ключевое слово static
- статический метод принадлежит всему классу
- наследуются
Приватные и защищённые методы и свойства класса
- по умолчанию все свойства и методы - публичны
- чтобы сделать свойство только для чтения нужно сделать геттер без сеттера:
- защищенные поля и методы наследуются
- защищенные поля и методы имеют вид
_power
- приватные поля и методы не наследуются
- приватные поля и методы имеют вид
#waterLimit
- в классе могут быть одинаково названные поля с разными модификаторами
Примеси
Примеси позволяют получить функциональность нескольких классов без наследования.
Примесь – это класс, методы которого предназначены для использования в других классах, причём без наследования от примеси:
// примесь
let sayHiMixin = {
sayHi() {
alert(Привет, ${this.name}
);
},
sayBye() {
alert(Пока, ${this.name}
);
}
};
// использование:
class User {
constructor(name) {
this.name = name;
}
}
// копируем методы (использование примеси)
Object.assign(User.prototype, sayHiMixin);
// теперь User может сказать Привет
new User(“Вася”).sayHi(); // Привет, Вася!
Флаги свойств объектов
Свойство (поле или метод) - это компонент объекта в виде пары “ключ(название свойства)-значение”.
Флаги свойств - это специальные скрытые атрибуты (по умолчанию true):
- writable
– еслиtrue
, свойство можно изменить, иначе оно только для чтения.
- enumerable
– еслиtrue
, свойство перечисляется в циклах, в противном случае циклы его игнорируют.
- configurable
– еслиtrue
, свойство можно удалить, а эти атрибуты можно изменять, иначе этого делать нельзя (если false
- то с этим свойством абсолютно ничего нельзя сделать).
Object.getOwnPropertyDescriptor() - позволяет получить информацию (дескрипторы) свойства:
let user = {
name: “John”
};
let descriptor = Object.getOwnPropertyDescriptor(user, ‘name’);
alert( JSON.stringify(descriptor, null, 2 ) );
/* дескриптор свойства:
{
“value”: “John”,
“writable”: true,
“enumerable”: true,
“configurable”: true
}
*/
Обработка ошибок try..catch и try..catch..finally
try..catch позволяет «ловить» ошибки времени выполнения и вместо падения делать что-то более осмысленное, работает синхронно:
try {
alert(‘Начало блока try’); // (1) <–
lalala; // ошибка, переменная не определена!
alert(‘Конец блока try (никогда не выполнится)’); // (2)
} catch(err) {
alert(Возникла ошибка!
); // (3) <–
}
Блокfinally
используют, когда мы начали что-то делать и хотим завершить это вне зависимости от того, будет ошибка или нет
Модули
Модуль - это файл со скриптом js (всегда в strict режиме):
- Директива export
отмечает переменные и функции, которые должны быть доступны вне текущего модуля
- Директива import
позволяет импортировать функциональность из других модулей
- при импорте модуля выполняется код в нем
- при импорте одного модуля несколько раз, его код выполнится только 1 раз
- Если нужно много раз вызывать код функции в модуле, ее надо сделать экспортируемой
- Модуливсегдавыполняются в отложенном (deferred) режиме, когда вся HTML-страница будет готова
- Выражение import(module)
динамически загружает модуль и возвращает промис, результатом которого будет объект модуля
Декораторы
Декораторы - это Функции-обертки:
- добавляют функциональность исходной функции, не меняя ее код
- не могут применяться к методам объекта (т.к. декоратор передаёт вызов оригинальному методу, но без контекста (this))
Пример:
function slow(x) {
// здесь могут быть ресурсоёмкие вычисления
alert(Called with ${x}
);
return x;
}
//декоратор для кэширования
function cachingDecorator(func) {
let cache = new Map(); //здесь хранятся кэшированные значения
return function(x) {
if (cache.has(x)) { // если кеш содержит такой x,
return cache.get(x); // читаем из него результат
}
let result = func(x); // иначе, вызываем функцию
cache.set(x, result); // и кешируем (запоминаем) результат
return result;
};
}
//декорируем функцию slow
slow = cachingDecorator(slow);
alert( slow(1) ); // slow(1) кешируем
alert( “Again: “ + slow(1) ); // возвращаем из кеша
Асинхронность в Javascript
Асинхронный код в JavaScript может быть написан разными способами:
- callback (функция, которая будет вызвана по завершению асинхронного действия)
- promise
- async/await
callback
callback - это функция обратного вызова:
function asyncFunction(callback) {
console.log(“Перед вызовом коллбека”);
callback();
console.log(“После вызова коллбека”);
}
function callbackFunc() {
console.log(“Вызов коллбека”);
}
asyncFunction(callbackFunc);
Promise
Promise - это объект, представляющий результат успешного или неудачного завершения асинхронной операции.
Промис может находиться в одном из следующих состояний:
- pending (состояние ожидания): начальное состояние, промис создан, но выполнение еще не завершено
- fulfilled (успешно завершено): действие, которое представляет промис, успешно завершено
- rejected (завершено с ошибкой): при выполнении действия, которое представляет промис, произошла ошибка
//resolve и reject - это колбэки в случае успешного/неуспешного выполнения кода промиса
const myPromise = new Promise(function(resolve){
console.log(“Выполнение асинхронной операции”);
resolve(“Привет мир!”);
});
//получение результата из промиса
myPromise.then(function(value){
console.log(Из промиса получены данные: ${value}
);
})
Функции-обработчики then, catch, finally получают результат промиса.
Цепочка промисов
Цепочка промисов - это цепочка обработчиков then
:
- promise.then()
возвращает промис или любой пользовательский объект, реализующий Thenable (метод then)
- Если промис завершается с ошибкой, то управление переходит в ближайший обработчик catch
, т.к. функция промиса имеет неявный try..catch, в котором при исключении возвращает reject
Async/await
Async/await - это синтаксический сахар для работы с промисами.
- await - это аналог promise.then
- Ключевое словоawaitзаставит интерпретатор JavaScript ждать до тех пор, пока промис справа не выполнится:
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(“готово!”), 1000)
});
let result = await promise; // будет ждать, пока промис не выполнится
alert(result); // “готово!”
}
Функция-конструктор
Функция-конструктор - позволяет создавать много однотипных объектов с помощью оператора new:
function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User(“Jack”);
Сетевые запросы
Сетевые запросы:
- fetch (основан на промисах):
//GET-запрос
let response = await fetch(url, [options]);
if (response.ok) { // если HTTP-статус в диапазоне 200-299
// получаем тело ответа (см. про этот метод ниже)
let json = await response.json();
} else {
alert(“Ошибка HTTP: “ + response.status);
}
//POST-запрос
let response = await fetch(‘/article/formdata/post/user’, {
method: ‘POST’,
body: new FormData(formElem)
});
——————————————
AbortController - класс для отмены асинхронных задач:
let controller = new AbortController();
fetch(url, {
signal: controller.signal
});
//прервать выполнение fetch (выбрасывается AbortError)
controller.abort();
——————————————
Добавление заголовков в запрос:
let response = await fetch(‘https://site.com/service.json’, {
method: ‘PATCH’,
headers: {
‘Content-Type’: ‘application/json’,
‘API-Key’: ‘secret’
}
});
——————————————-
//Добавление Куки:
fetch(‘http://another.com’, {
credentials: “include”
});
XMLHttpRequest
XMLHttpRequest - встроенный в браузер объект для HTTP-запросов без перезагрузки страницы (ajax-запрос), может работать с любыми форматами данных:
const xhr = new XMLHttpRequest();
// GET-запрос к ресурсу /hello
xhr.open(“GET”, “/hello”);
// обработчик получения ответа сервера
xhr.onload = () => {
if (xhr.status == 200) { // если код ответа 200
console.log(xhr.responseText); // выводим полученный ответ на консоль браузера
} else { // иначе выводим текст статуса
console.log(“Server response: “, xhr.statusText);
}
};
xhr.send(); // выполняем запрос
WebSocket
WebSocket - протокол, обеспечивающий обмен данными (в виде пакетов) через постоянное соединение без доп. HTTP-запросов (подходит для онлайн-игр, приложений реального времени) со сжатием данных:
//ws - аналог HTTP, wss - аналог HTTPS
let socket = new WebSocket(“wss://javascript.info/article/websocket/chat/ws”);
socket.send(“Hello”);
socket.onmessage = function(event) {
let message = event.data;
}
Server Sent Events (SSE)
Server Sent Events (SSE) - основан на протоколе HTTP, поддерживает постоянное соединение:
- однонаправленность (данные посылает только сервер)
- автоматическое переподключение
let eventSource= new EventSource(“https://another-site.com/events”, {
withCredentials: true
});
eventSource.onmessage = function(event) {
console.log(“Новое сообщение”, event.data);
};
Каррирование
Каррирование - то трансформация функций таким образом, чтобы они принимали аргументы не какf(a, b, c)
, а какf(a)(b)(c)
, т.е. можно фиксировать некоторые аргументы, если они часто повторяются:
function log(date, importance, message) {
alert([${date.getHours()}:${date.getMinutes()}] [${importance}] ${message}
);
}
//применим к функции log каррирование
log = _.curry(log);
// logNow будет частичным применением функции log с фиксированным первым аргументом
let logNow = log(new Date());
let debugNow = logNow(“DEBUG”);
//теперь можно логировать без необходимости передавать фиксированные параметры
debugNow(“message”); // [HH:mm] DEBUG message
Основные объекты интернационализации Javascript
- Intl.Collator (Умеет правильно сравнивать и сортировать строки):
let collator = new Intl.Collator([locales, [options]]);
let result = collator.compare(str1, str2); - Intl.DateTimeFormat (Умеет форматировать дату и время в соответствии с нужным языком):
let formatter = new Intl.DateTimeFormat([locales, [options]])
//использование
formatter.format(date); - Intl.NumberFormat (Умеет форматировать числа в соответствии с нужным языком)
Методы форматирования примитивных типов
Методы форматирования также поддерживаются в обычных строках, датах, числах:
date.toLocaleString(“ru”, { year: ‘numeric’, month: ‘long’ })
number.toLocaleString(“ru”)
Функции-генераторы
Функции-генераторы могут порождать (yield) множество значений одно за другим, по мере необходимости
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let generator = generateSequence();
//Перебор генератора в цикле
for(let value of generator) {
alert(value); // 1, затем 2, затем 3
}
Основным методом генератора является next()
, который запускает выполнение кода функции-генератора до ближайшего yield
.
Браузерное окружение
Браузерное окружение предоставляет свои объекты и дополнительные функции, в дополнение базовым языковым:
- DOM (объектная модель документа, которая представляет все содержимое страницы в виде объектов, которые можно менять) - представление HTML-документа в виде дерева тегов, в котором каждый узел является объектом:
- теги - это узлы-элементы
- текст внутри элементов - это текстовые узлы или просто элементы
- тег html - это корневой узел
Навигация по DOM-элементам
document - главный элемент в DOM, из которого можно получить доступ к любому узлу:
- document.getElementById(id)
- document.body.firstElementChild
- document.body
- document.head
- document.body.childNodes
Особенности DOM-элементов:
- только для чтения
- коллекции DOM-элементов обновляются автоматически
- коллекции DOM-элементов перебираются в цикле
Иерархия классоы DOM-узлов
- EventTarget - это корневой «абстрактный» класс для всего, обеспечивает поддержку событий.
- Node - «абстрактным» класс, основа для всех DOM-узлов, предоставляет общие свойства DOM-узлов
- Element - это базовый класс для DOM узлов-элементов
- HTMLElement - базовый класс для всех HTML-элементов
Браузерные события
Браузерное событие - это сигнал от браузера о том, что что-то произошло (click, contextmenu, mouseover и т.д.)
Обработчик события - функция, которая сработает, как только событие произошло:
elem.onclick = function() {
alert(‘Спасибо’);
}
Всплытие и погружение события
Всплытие - это когда на элементе происходит событие, обработчики сначала срабатывают на нём, потом на его родителе, затем выше и так далее, вверх по цепочке предков.
Погружение - событие сначала идет сверху вниз до целевого элемента (фаза погружения), а потом уже вызываются обработчики по цепочке снизу вверх
Делегирование событий
Делегирование событий - применяется при использовании общего обработчика для однотипных элементов (например строк таблицы):
table.onclick = function(event) {
//возвращает ближаейго предка с указанным тегом (ячейка)
let td = event.target.closest(‘td’); // (1)
if (!td) return; // (2)
//проверка, что ячейка принадлежит именно этой табилце
if (!table.contains(td)) return;
highlight(td); // функция подсветки ячейки
};
Генерация пользовательских событий Event
Event - встроенный класс события, его наследники:
- UIEvent
- FocusEvent
- MouseEvent
- WheelEvent
- KeyboardEvent
- CustomEvent
- класс для кастомного события (имеет доп. свойство detail, в котором можно передавать данные в обработчик):
//назначение обработчика события с названием “hello”
elem.addEventListener(“hello”, function(event) {
alert(event.detail.name);
});
//создание своего кастомного события с названием “hello”
elem.dispatchEvent(new CustomEvent(“hello”, {
detail: { name: “Вася” }
}));
Событийный цикл
Событийный цикл - это бесконечный цикл движка JS, в котором он ожидает макрозадачи (выполннение скрипта, браузерные события, таймеры и т.д.) и выполняет их, начиная с самой старой из очереди задач.
- Рендеринг никогда не происходит во время выполнения задачи движком, только после
- лучше разбивать долгую задачу на подзадачи и выполнять их в интервале времени
- после каждой макрозадачи движок исполняет все задачи из очередимикрозадач
- Микрозадача - обработчик из цепочки обработчиков промиса
Куки
Куки - это небольшие строки данных, которые хранятся в браузере, устанавливаются сервером в заголовке Set-Cookie
(c уникальным идентификатором сессии):
document.cookie = “user=John”;
Настройки куки:
- expires (срок действия куки (по умолчанию куки удаляются при закрытии браузера))
- domain (домен, где доступен файл куки)
- path (путь до файлов страниц, которые могут исп. этот куки)
- httpOnly (запрещает любой доступ к куки из JavaScript)
- secure (куки будут передаваться только по протоколу HTTPS)
JavaScript-анимации
JavaScript-анимации:
- с помощью setInterval (реализуются через последовательность кадров, каждый из который немного меняет HTML/CSS-свойства)
- с помощью requestAnimationFrame (изменения элемента группируется с другими анимациями (чтобы отрендерить все за 1 проход), поэтому нагрузка браузера снижается, анимация выполняется не по таймеру, а в ближайшее доступное для браузера время)
Хранение данных в браузере
localStorageи sessionStorage - объекты, позволяющие хранить пары ключ/значение в браузере (данные не теряются после обновления страницы (для sessionStorage) и перезапуска браузера (для localStorage))
Proxy
Proxy - встроенный объект, оборачивается вокруг другого объекта и может перехватывать разные действия с ним.
let proxy = new Proxy(target, handler);
- handler (конфигурация прокси: объект с «ловушками» - методами, которые перехватывают разные операции)
let numbers = [0, 1, 2];
//прокси перехватывает операцию get и возвращает 0, если элемента в массиве нет
numbers = new Proxy(numbers, {
get(target, prop) {
if (prop in target) {
return target[prop];
} else {
return 0; // значение по умолчанию
}
}
});
Shadow DOM
Shadow DOM - для инкапсуляции элементов в сложных элементах управления:
//реализация такого элемента гораздо сложнее
<input></input>
Слабая ссылка WeakRef
WeakRef - это объект, содержащий слабую ссылку на другой объект, которая не препятствует удалению объекта сборщиком мусора.
WeakRef обычно используется:
- для создания кешей или ассоциативных массивов, в которых хранятся ресурсоёмкие объекты (позволяет избежать предотвращение удаления этих объектов сборщиком мусора только на основе их присутствия в кеше или ассоциативном массиве)
- для отслеживание объектов DOM
Регулярные выражения
Регулярные выражения - средство поиска и замены в строке по шаблону