code_notes
71 subscribers
136 photos
1 video
134 links
учусь делать веб

обратная связь: t.me/dmorenogogoleva
Download Telegram
статические методы

при объявлении помечаются словом static

присваиваются не классу, а его prototype

class User {
static staticMethod() {
...
}
}

то же самое что
User.staticMethod = function() {
...
};
обычно статические методы используются для реализации функций, принадлежащих классу, но не к каким-то конкретным его объектам.

обычно вызываются из класса

class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}

static createTodays() {
return new this("Сегодняшний дайджест", new Date());
}
}

let article = Article.createTodays();
из экземпляра класса этот метод вызвать нельзя
пример из реальной жизни

метод getInitialProps, который предоставляется фреймворком next
он выполняется на сервере и может снабдить нас полезнейшей информацией типа текущего урла

статейка о том, как можно побыстрее фетчить данные с помощью этого метода
https://nextjs.org/learn/basics/fetching-data-for-pages
приватные методы и свойства

для того, чтобы юзать свойство снаружи удобнее всего использовать get как геттер и функцию как сеттер
Чтобы поймать unhandledrejection нужно навесить обработчик на window

window.addEventListener('unhandledrejection', function(event) {
// объект события имеет два специальных свойства:
alert(event.promise); // [object Promise] - промис, который сгенерировал ошибку
alert(event.reason); // Error: Ошибка! - объект ошибки, которая не была обработана
});
статические методы промисов

1. Promise.all — принимает массив промисов (может принимать любой перебираемый объект, но обычно используется массив) и возвращает новый промис. Новый промис завершится, когда завершится весь переданный список промисов, и его результатом будет массив их результатов

Если любой из промисов завершится с ошибкой, то промис, возвращённый Promise.all, немедленно завершается с этой ошибкой.

2. Promise.allSettled !нужен полифил!
работает так же как Promise.all, но если один из промисов падает с ошибкой, то он не завершается с ошибкой, а просто передает в массив ответов ошибку вместо результата

3. Promise.race — очень похож на Promise.all, но ждёт только первый промис, из которого берёт результат (или ошибку).

4. Promise.resolve(value) — создаёт успешно выполненный промис с результатом value
let promise = new Promise(resolve => resolve(value));


5. Promise.reject — создаёт промис, завершённый с ошибкой error

let promise = new Promise((resolve, reject) => reject(error));

На практике этот метод почти никогда не используется.
// await будет ждать массив с результатами выполнения всех промисов
let results = await Promise.all([
fetch(url1),
fetch(url2),
...
]);
Генераторы могут генерировать бесконечно

Почему-то я была уверена, что знаю джаваскрипт. Если не глубоко, то хотя бы знаю про все сущности и их синтаксис. И тут я дочитала до главы про генераторы и ору.

Мне казалось, что генераторы это просто функции-фабрики и я их имплементировала уже пятьсот раз.
Но я ошибалась.

самый простой генератор выглядит так:
function* generateSequence() {
yield 1;
yield 2;
return 3;
}

🤨🤨🤨

а вот его использование:
let generator = generateSequence();

generator.next()
// {value: 1, done: false}

generator.next()
// {value: 2, done: false}

generator.next()
// {value: 3, done: true}

😐😐😐

первая ценность генераторов в том, что они являются перебираемыми объектами
function* generateSequence() {
yield 1;
yield 2;
yield 3;
}

let generator = generateSequence();

for (let value of generator) {
console.log(value)
}
// 1, 2, 3

из генератора можно сделать массив вот так:
[...generateSequence()]

// [1, 2, 3]

вторая ценность генераторов состоит в том, что их можно вкладывать друг в друга
это называется «композиция генераторов»
function* generateSequence(start, end) {
for (let i = start; i <= end; i++) yield i;
}

function* generatePasswordCodes() {

yield* generateSequence(48, 57);

yield* generateSequence(65, 90);

yield* generateSequence(97, 122);

}

let str = '';

for(let code of generatePasswordCodes()) {
str += String.fromCharCode(code);
}

// "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

третья ценность генераторов — способность обмениваться данными с вызывающим кодом
🤯🤯🤯

Чтобы это сделать, нам нужно вызвать generator.next(arg) с аргументом. Этот аргумент становится результатом yield.
function* gen() {
let ask1 = yield "2 + 2 = ?";

console.log(ask1); // 4

let ask2 = yield "3 * 3 = ?"

console.log(ask2); // 9
}

const generator = gen();

console.log(generator.next().value);

console.log(generator.next(4).value);

console.log(generator.next(9).done);
цитата из учебника:
1. Первый .next() начинает выполнение… Оно доходит до первого yield.

2. Результат возвращается во внешний код.

3. Второй .next(4) передаёт 4 обратно в генератор как результат первого yield и возобновляет выполнение.

4. …Оно доходит до второго yield, который станет результатом .next(4).

5. Третий next(9) передаёт 9 в генератор как результат второго yield и возобновляет выполнение, которое завершается окончанием функции, так что done: true.

Получается такой «пинг-понг»: каждый next(value) передаёт в генератор значение, которое становится результатом текущего yield, возобновляет выполнение и получает выражение из следующего yield.
картинка
как используются генераторы в реальной жизни?

судя по всему, очень редко
но можно например сделать набор псевдослучайных чисел для каких-нибудь тестов

function* pseudoRandom(seed) {
let previous = seed;

while(true) {
previous = previous * 16807 % 2147483647
yield previous;
}

};

let generator = pseudoRandom(1);

generator.next().value;
// 16807

generator.next().value;
// 282475249

generator.next().value;
// 1622650073

подробности можно почитать здесь: https://learn.javascript.ru/generators
также в реальной жизни часто используются асинхронные генераторы для постраничного фетчинга данных (считается, что это очень удобно)

скоро я узнаю это точно, потому что в новом проекте у нас мобикс, а с ним принято использовать все генераторные радости
<script type="module">

1. всегда включена директива use strict
2. отложенное (deferred) выполнение по умолчанию
3. атрибут async работает во встроенных скриптах
4. для загрузки внешних модулей с другого источника, он должен ставить заголовки CORS
5. дублирующиеся внешние скрипты игнорируются
6. у модулей есть своя область видимости, обмениваться функциональностью можно через import/export
В реальной жизни модули в браузерах редко используются в «сыром» виде. Обычно, мы объединяем модули вместе, используя специальный инструмент, например Webpack и после выкладываем код на рабочий сервер.

Одно из преимуществ использования сборщика – он предоставляет больший контроль над тем, как модули ищутся, позволяет использовать «голые» модули и многое другое «своё», например CSS/HTML-модули.

Сборщик делает следующее:

Берёт «основной» модуль, который мы собираемся поместить в <script type="module"> в HTML.
Анализирует зависимости (импорты, импорты импортов и так далее)
Собирает один файл со всеми модулями (или несколько файлов, это можно настроить), перезаписывает встроенный import функцией импорта от сборщика, чтобы всё работало. «Специальные» типы модулей, такие как HTML/CSS тоже поддерживаются.
В процессе могут происходить и другие трансформации и оптимизации кода:
Недоступный код удаляется.
Неиспользуемые экспорты удаляются («tree-shaking»).
Специфические операторы для разработки, такие как console и debugger, удаляются.
Современный синтаксис JavaScript также может быть трансформирован в предыдущий стандарт, с похожей функциональностью, например, с помощью Babel.
Полученный файл можно минимизировать (удалить пробелы, заменить названия переменных на более короткие и т.д.).

Если мы используем инструменты сборки, то они объединяют модули вместе в один или несколько файлов, и заменяют import/export на свои вызовы. Поэтому итоговую сборку можно подключать и без атрибута type="module", как обычный скрипт:
<script src="bundle.js"></script>
proxy

обёртка вокруг объекта, которая «по умолчанию» перенаправляет операции над ней на объект, но имеет возможность перехватывать их.

const numbers = [0, 1, 2];


const numbersProxy = new Proxy(numbers, {
get(target, prop) {
if (prop in target) {
return target[prop];
} else {
return 0;
}
}
});

numbers[1]
// 1

numbers[123]
// 0
eval

функция eval позволяет выполнять строку кода

let value = eval('1+1');

// value = 2;


как я поняла, eval это рудимент из глубины веков и в наше время его использовать стыдно и незачем. Также он мешает минификаторам минифицировать.

не используйте eval
«eval is evil»
комментарий к главе про каррирование
каррирование

программисткое понятие, обозначает функцию с множеством скобочек. Каррирование нужно для применения функций по частям. Иногда это действительно бывает удобно.

const curry = (a) => (b) => a + b;

const plusTwo = curry(2)

plusTwo(3)
// 5
итак я дочитала первую часть учебника
из чего же состоит джаваскрипт по впечатлениям оттуда

10% — типы данных, разные типы данных, символы, мапы, викмапы, массивы, объекты (про объекты будет чуть позже), число не отличить от строки, когда оно приходит с сервера, конст не работает, смиритесь с этим

50% — объекты. Давайте создавать объекты, давайте наследовать объекты, давайте объектам задавать прототипы, всё есть объект. Ни в коем случае не теряйте контекст

30% — функции. Функции могут создавать объекты, можно через функции устанавливать прототип для объектов (но это не совсем тот прототип, что передается через объекты), вот новый синтаксис для создания объектов через функции, не забудьте про конструктор, но есть ещё и обычные функции

10% — промисы, генераторы, ошибки, ивент луп, функциональное программирование