Skip to content

Latest commit

 

History

History
324 lines (210 loc) · 21.2 KB

02. Джаваскрипт для самых начинающих.md

File metadata and controls

324 lines (210 loc) · 21.2 KB

Джаваскрипт для самых начинающих

Как перестать его бояться и всё-таки освоить

Сегодня мы говорим про Джаваскрипт: боль и страх новичков, а на самом деле зря они к нему так относятся. Поехали!

Основы любого языка программирования

Зачем нужны языки программирования? Программирование это эм, программирование компьютера на выполнение нужной вам программы. Программы пишутся на языке программирования и подчиняются алгоритму.

Пример из реальной жизни: вы каждый день просыпаетесь, чистите зубы, завтракаете, идёте в метро, едете на работу, работаете работу, возвращаетесь обратно. Всё это — алгоритм, вы выполняете программу. Ваш каждый день (если он такой) — детерминирован, то есть предсказуем.

То же самое и с программами: вы заставляете компьютер отработать программу, которую вы написали. Заставляете через код, который пишете на каком-то языке программирования.

Бывают простые скрипты, которые ни от чего не зависят: например, парсинг сайта. Вы написали скрипт на каком-нибудь Nightmare.js, он зашёл на нужный сайт, спарсил вам нужные данные, отдал. Никакого взаимодействия нет, тупой скрипт с тупым алгоритмом.

Или те же базы данных: написал скрипт (на SQL), который либо отдаёт данные, либо обновляет, ну и готово. Примитивно, конечно, но идею вы понимаете.

Фронтэнд (да и бэкэнд, да и мобильные приложения, да и многое другое) отличаются интерактивностью: пользователь взаимодействует с программой и она выполняет выражения.

В любом случае всё сводится к данным: либо с ними производится работа (обновление), либо их отображают.

Данные

Но что такое данные? Это информация. Но, к сожалению, компьютеры не очень умны и неспособны распознать данные разных типов, поэтому приходится этим заниматься разработчикам. Эх, побыстрее бы пришёл AI и научился парсить что угодно!

Типы бывают разные: от простейших типа чисел до сложных типа монад. Джаваскрипт в этом плане унылый язык, да и типизация там нестрогая — как прочтёте урок, посмотрите Wat. Например, если вы попробуете выполнить '1' + 2, то Джс выдаст '12', а Хаскелль (язык со строгой типизацией) — ошибку No instance for (Num Char) arising from a use of ‘+’ и будет прав.

Давайте разберём типы (кстати, это первая ссылка на MDN (Mozilla Developer Network) — наряду с Google Developers For Web это один из основных источников информации).

Типы данных

Числа — Number

Число, например, 1 или 123782.

Дробные числа — Float

Дробное число, 1.24 или 3.142324221,

Строки — String

Строка, в основном про текст, например, 'hello world' (могут использоваться и двойные кавычки "", и ``).

Массивы — Array

Массив — это список элементов, упорядоченных по индексу, начиная с нуля. Представьте себе стопку книг Большой Советской Энциклопедии из 30 томов. За каждый элемент массива возьмём название тома:

['1-ый том', '2-ой том', '3-ий том', ..., '30-ый том']

Первый том будет под нулевым индексом, 30-ый — под двадцать девятым. Обратиться к элементу массива можно по индексу.

В массиве могут быть данные разных типов, можно даже смешивать, но не рекомендую — сложно работать с массивом, где всё намешано как в помойке.

Объекты — Object

Мощный тип данных, который можно представить как пару "ключ" — "значение". Если в массиве у нас элементы идут в чётком порядке, то в объекте мы можем сами задавать ключ, по которому будем обращаться.

{
  hello: "world",
  items: [0, 1, 2, 3, 4],
  mySuperNumber: 1,
  myFloatNumber: 0.24,
  myNestedObject: {
    hello: "again"
  }
}

null

Пустой тип данных. Как черная дыра. no value, если цитировать.

Уточню, что null по типам относится к объектам. Джаваскрипт 🤷

undefined

Незаданный тип данных. Отличие от null в том, что мы объявили константу или переменную, но значение ей ещё не задали, а null может как раз показывать, что значения нет.

Например, в вашем приложении два состояния: только что открытая страница (ещё незагруженные данные) и запрошенные данные с сервера. Нам нужно отобразить два состояния картинки: если мы ещё не загружали данные, то будет undefined, если загрузили и сервер сказал, что её нет, то null.

Вот ещё пример: у вас в данных могут быть как null, так и undefined:

{
  "id": 1,
  "name": "Evgeny Rodionov"
}

{
  "id": 1,
  "name": "Evgeny Rodionov",
  "city": null
}

В первом случае пользователь ещё не задал город, во втором — уже указал, что не хочет его указывать.

class

Классы это грубо говоря (очень грубо говоря) объект с данными и функциями (они называются методами).

class Greeting {
  sayThis(toWhom) {
    return `Hello ${toWhom}!`;
  }
}

// вызываем
new Greeting().sayThis("and fuck you"); // Hello and fuck you!

Булеаны — Boolean

(да, я не смог перевести на русский)

Это тип данных, который отвечает за истинность: бывает либо true, либо false. Допустим, если вы сравниваете выражения друг с другом, то это сравнение приведется к булеану:

42 === 42; // true
42 === "42"; // false
42 == "42"; // true (потому что `==` это слабое сравнение, которое не учитывает типы — поэтому его нельзя использовать https://eslint.org/docs/rules/eqeqeq.html)

Как со всем этим работать? Прикольно, конечно, что есть какие-то данные, но дальше-то что?

Выражения (expressions)

А дальше у нас работа с этими данными через выражения. Выражения — это второй столп программирования, потому что весь код состоит из них. Код и есть выражения.

Но, конечно же, эти выражения должны быть как-то структурированы! Нельзя же просто написать файл my-awesome-site.js и туда в полотно накидать 10 тысяч строк, верно же? Давайте поговорим про то, как структурируют код.

Константы и переменные (const, var, let)

Неизменяемая ссылка на значение. Тут важно каждое слово:

  • неизменяемая: заменить нельзя,
  • ссылка: не само значение, а только ссылка на него.

Объявляется через const [название] = [значение], например

const x = "hello world";

Почему я сделал акцент на ссылке?

Если вы попытаетесь сделать x = 'fuck this', то вам выдаст ошибку: Uncaught TypeError: Assignment to constant variable..

Но если вы попытаетесь что-нибудь сделать с массивом или объектом, то всё пройдёт нормально.

const x = [0, 1, 2, 3];

x.push(4); // [0, 1, 2, 3, 4]

Это нюанс работы const: нельзя изменять ссылку, но можно менять значение в ней.

Переменные

Переменные названы так, потому что их значения можно сменить:

let x = "hello world";
// или var x = "hello world"
x = "fuck this";

Отличие let от var в области видимости. Об этом поговорим позже.

Когда использовать const, а когда let?

Всё просто: код должен быть предсказуемым. Сравните два сценария:

  • при const: о, здесь X равен 42,
  • при let или var: так, здесь X равен 42, НО ТЕПЕРЬ НУЖНО ПРОВЕСТИ РАССЛЕДОВАНИЕ И ПОНЯТЬ, ГДЕ ОН СТАНОВИТСЯ НЕ 42.

Предсказуемости мало.

Всегда использовать const и никогда — let и var

Операторы это специальная конструкция языка и они знакомы вам из математики: +, -, >, <. Складывание, вычитание, сравнение (которое, как вы помните, приводятся к булеанам).

Логические операторы

Если вам нужно объединить несколько сравнений, то есть логические операторы И, ИЛИ и НЕ:

if (x && y) {
  // блок кода который отработает если будет true
}

Блоки кода и функции

Вы заметили {} ? Это блок кода. И это следующая важная часть языка: каждый код (или выражения) можно сгруппировать в блок. Часто это используется в сравнениях как в примере выше, а ещё чаще — в функциях.

Функции это блок кода, в который можно передать аргументы и который может вернуть результат. Пример:

function sayHello(toWhom) {
  const message = "Hello, " + toWhom;

  return message;
}

sayHello("Evgeny"); // Hello, Evgeny.

Давайте разбирать?

  • function — резервное слово, которое означает, что дальше будет код;
  • sayHello — название функции,
  • () — список аргументов, в нашем случае он один (toWhom),
  • const message = "Hello, " + toWhom — вычисление выражения "Hello, " + toWhom (тут используется оператор + для конкатенации (складывания) строк) в константу message;
  • return message — возврат значения, которое находится под константой message;
  • sayHello('Evgeny') — вызов функции с одним аргументом 'Evgeny' (где 'Evgeny' это строка, без кавычек это было константой или переменной).

Функции бывают разные:

// Function Declaration
function f(...arguments) {}

// Function Expression
const f = function(...arguments) {};

// Named Function Expression
const f = function func(...arguments) {};

// Arrow functions (ES2015+)
const f = (...arguments) => {};

В чём отличие? Это то, что у вас будут спрашивать на собеседованиях и то, что вам нужно помнить, чтобы не выстрелить себе в ноги.

  • FD — можно объявить ниже вызова, потому что создаётся на этапе парсинга (разбора программы);
  • FE — нельзя объявить, потому что создаётся когда код отработает на строчке с этой функцией;
  • NFE — внутри функции можно обратиться к функции по её имени func.
  • AF — когда вам нужно чтобы this был от родителя, а не от функции

Что когда использовать? Да без разницы, любой адекватный линтер запрещает писать говнокод и объявлять функции позже её использования — в этом самая большая проблема Function Declaration.

this

JavaScript is like LSD

You have no idea where you are and what "this" even means.

— Andrzej Krzywda (@andrzejkrzywda) January 19, 2016
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

this это специальный объект, в котором находится то, что доступно этому блоку кода. Это часто используется в классах (чтобы обратиться к методу класса):

class MyTestClass {
  constructor() {
    this.myField = 1;
  }

  getMyField() {
    return this.myField;
  }
}

new MyTestClass().getMyField(); // 1

Методы прототипов

Джс построен на системе прототипов (об этом узнаете позже, когда подрастёте) и нюанс в том, что у каждого типа данных есть свой набор методов.

Например, у массива есть map, filter, reduce и куча других методов. Они бывают мутабельными и иммутабельными: мутабельные изменяют изначальный массив, а иммутабельный возвращает новый. Разберём на примерах?

// заведём массив
const fruits = ["apple", "orange", "pear"];

// заведём функцию, которая разворачивает строку
// в Джсе, конечно же, такой функциональности по-умолчанию нет
// https://stackoverflow.com/a/959004/2389634
function reverseString(string) {
  // мы вызываем метод .split() у строки — он строку превращает в массив с символом
  // затем разворачиваем массив через метод .reverse()
  // и собираем обратно через метод массива .join() — он превращает массив в строку
  return string
    .split("")
    .reverse()
    .join("");
}

// пройдёмся по нему мапом, чтобы получить новый массив и положить его в reversedFruits
const reversedFruits = fruits.map(function(fruit, index) {
  // .map это функция, в неё аргументом передаётся другая функция,
  // в которую приходят два аргумента — элемент и индекс
  // эта функция вызывается на каждом элементе массива
  // и эта функция должна вернуть новый элемент, который будет доступен по ключу

  return reverseString(fruit);
});

// что у нас в reversedFruits?
console.log(reversedFruits); // ["elppa", "egnaro", "raep"]

Я рекомендую пройтись по MDN и прочитать про методы встроенных типов: String, Number, Float, Array, Object.

Итог

Урок получился насыщенным: больше полутора тысяч слов в нём, но вот что я бы хотел сказать.

Нам этот урок нужен как фундамент для будущих: вы должны знать немного Джаваскрипта, чтобы не плавать в Реакте.

Достаточно ли его? Да, ведь прежде чем придти к теории категорий, вы должны знать про числа и операторы сложения-умножения-деления-вычитания, базовую арифметику, в общем.

Очень часто люди думают что надо прочитать какую-нибудь книжку (часто советуют YDKJS или learn.javascript.ru) или пройти курс по "чистому" Джаваскрипту, причём обязательно нужно это сделать до изучения каких-либо библиотек или фреймворков!

Нюанс в том, что Джаваскрипт не очень сложный язык. Да, у него есть подводные камни (и мы их разберём обязательно), но по моей практике достаточно знать того, что выше, чтобы писать на Реакте — а как вы помните из предыдущего урока, Реакт это чистый Джаваскрипт (а не шаблонизатор), поэтому опыт вы наработаете на реальном проекте. Это не так скучно, как в консоли долбить alert('Hello world') и намного полезнее.

Поработайте джуном или просто на фрилансе пару месяцев, попрактикуйтесь на реальных задачах, а потом — зашлифуйте свои знания на Хекслете, говорят, у них сильная фундаменталика (лично я сам не пробовал). Но помните, что без практики она будет лишь в тягость и непонятной.