Данное руководство содержит информацию по базовым конструкциям языка программирования TypeScript
Для работы с руководством можно использовать песочницу: https://www.typescriptlang.org/play
Язык программирования — формальный язык, предназначенный для записи компьютерных программ. Язык программирования определяет набор правил, определяющих внешний вид программы и действия, которые выполнит исполнитель (обычно — ЭВМ) под её управлением.
TypeScript — это язык программирования. Он обладает своими особенностями, которые мы будем рассматривать в данном и других руководствах. Это улучшенный вариант JavaScript, который делает жизнь разработчиков легче, а большие приложения — надежнее.
TypeScript используют для:
console.log("Hello, world!")
Что такое console
, что такое log
мы разберёмся далее. Пока нам достаточно того, что данная строчка помогает взаимодействовать программе с внешним миром — выводит информацию на экран.
Задание: попробуйте отредактировать пример, чтобы программа выводила ваше имя.
console.log()
умеет выводить на экран не только строки. Его можно использовать как калькулятор:
console.log(2 + 2)
Задание: попробуйте отредактировать пример, чтобы программа сама считала и выводила периметр прямоугольника с шириной
7
и высотой14
.
Можно попытаться написать программу используя только console.log()
, но этого ужасно мало. Представьте как выглядел бы расчёт вещественных корней квадратного уравнения с помощью только console.log()
. Хочется в одном месте объявлять данные, в другом месте совершать над ними операции, только потом выводить результат на экран. Мы уже умеем выводить информацию на экран. А вот для того, чтобы хранить данные, потребуются переменные.
Переменная -- это символическое имя, которое используется для хранения и обращения к данным в памяти компьютера.
Пример объявления переменной:
let width: number = 7
var
-- ключевое слово, служит для объявления переменных.
width
-- имя переменной. С его помощью мы будем работать со значением, которое записано в переменную.
number
-- тип переменной. Тип переменной определяет значение, которое может храниться в переменной, так же определяет набор операций, которые мы можем выполнить над переменной.
=
-- оператор присваивания. Он служит для присваивания значения переменной
10
-- значение, которое будет присвоено переменной.
Давайте попробуем решить задачу расчёта периметра прямоугольника с использованием переменных:
let width: number = 7
let height: number = 14
let perimeter: number = 2 * (width + height)
console.log(perimeter)
В этом примере мы не только объявили численные переменные, но и совершили над ними арифметические операции, указали приоритет операций с помощью скобок, и даже присвоили переменной perimeter
результат этих операций.
Вообще говоря, компилятор TypeScript умеет сам выводить типы. Т.е. не всегда нужно явно указывать типы переменных, они могут быть выведены из тех значений, которые присваиваются переменным. Чтобы в этом убедиться, достаточно навести указатель мыши на имя переменной, во всплывающем окне будет отображён выведенный тип. Но на первых порах всё же рекомендуется явно указывать типы.
let width = 7
let height = 14
let perimeter = 2 * (width + height)
console.log(perimeter)
Задание: допишите программу выше, чтобы она выводила ещё и площадь (area) прямоугольника.
Как уже говорилось, тип переменной определяет значение, которое может храниться в переменной, так же определяет набор операций, которые мы можем выполнить над переменной.
Вот некоторый набор типов переменных, который мы можем встретить в языке TypeScript:
number
: действительные числа (и целые, и вещественные)string
: строкиboolean
: логическое значение true или false (истина или ложь)Array
: служит для хранения набора значений одного типаФункции
Составные типы
Интерфейсы
Классы
any
: произвольный тип (не рекомендуется использовать)null
сигнализирует о пустом значенииundefined
: сигнализирует о неопределённом значенииС типами number
и string
вы уже знакомы, с остальными мы познакомимся в своё время. Если не терпится, то можно ознакомиться в официальном руководстве
// а вот так выглядит комментарий. Он не исполняется
let a = 3;
let b = 2;
console.log(a + b); // сумма
console.log(a - b); // разность
console.log(a * b); // умножение
console.log(a / b); // деление
console.log(a ** b); // возведение в степень
// Приоритет операций можно задавать с помощью скобок
console.log(b + b * b);
console.log((b + b) * b);
Обратите внимание на точки с запятой в конце каждой строчки. В TypeScript рекомендуется ставить точки с запятой в конце каждого выражения.
let hello = "Привет";
let subject = "Мир";
// Строки можно складывать (конкатенация)
console.log(hello + subject);
console.log(hello + ", " + subject + "!");
// К строке даже можно прибавить число!
// Оно автоматически будет приведено к типу string
let area = 10;
console.log("Площадь равна " + area);
// Строки можно интерполировать (подставлять в шаблон)
console.log(`${hello}, ${subject}!`);
console.log(`Площадь равна ${area}`);
let a = true;
let b = false;
console.log(a, b);
// Можно сделать отрицание: true -> false, false -> true
console.log(!a, !b);
// Логическое "И": чтобы получилось true, нужно чтобы оба аргумента были true
console.log(a && b);
// Логическое "ИЛИ": чтобы получилось true, нужно чтобы хотя бы один аргумент был true
console.log(a || b);
// Можно получить в результате сравнения переменных других типов!
console.log(2+2 == 4);
// Следите за руками
console.log(2+2 == 4 && 2+2 == 5);
console.log(2+2 == 4 || 2+2 == 5);
let temperatures: Array<number> = [36.6, 37.7, 37.0, 36.9];
console.log(temperatures);
// Можно получить доступ по индексу
console.log(temperatures[0]);
// Можно складывать с другими массивами и получать новый
console.log(temperatures.concat([38.1, 38.2]));
// Можно сортировать
console.log(temperatures.sort());
/*
Так задаются
многострочные
комментарии
*/
// создаём свой собственный тип
type MyType = number | string | boolean;
const v: MyType = 5;
// создаем массив элементов нашего типа
let arr: Array<MyType> = [1, "hello", true];
// создаём тип из литералов (заранее определённых значений)
type Gender = "male" | "female"; // тип может хранить только два значения
let gender: Gender = "male";
console.log(gender); // будет выведено "male"
console.log(typeof gender); // будет выведено "string" - литерал строковый
Это далеко не все операции над типами. Экспериментируйте!
Ветвление — операция, применяющаяся в случаях, когда выполнение или невыполнение некоторого набора команд должно зависеть от выполнения или невыполнения некоторого условия.
Вернемся к примеру с периметром прямоугольника. Мы можем посчитать периметр для любого прямоугольника, у которого значения ширины и высоты положительны. Но тип number
позволяет задавать и отрицательные значения! Выхода два:
В общем виде вся конструкция ветвления выглядит следующим образом:
if (условие) {
// блок кода, который нужно выполнить, если условие == true
} else {
// блок кода, который нужно выполнить, если условие == false
}
Давайте попробуем решить проблему нулевых и отрицательных ширины и высоты
let width: number = 7
let height: number = 14
if (width > 0 && height > 0) {
let perimeter: number = 2 * (width + height)
console.log(perimeter)
} else {
console.log("Некорректная ширина или высота!")
}
Задание: напишите программу, которая по радиусу круга определит, больше его площадь 100, или нет.
Некоторые вещи хочется повторять снова и снова. Представьте, что вы хотите вывести строку "Hello, World!" пять раз. Без проблем можно написать:
console.log("Hello, world!");
console.log("Hello, world!");
console.log("Hello, world!");
console.log("Hello, world!");
console.log("Hello, world!");
Но это настоящее издевательство. Если бы хотели повторить эту операцию не пять раз, а 100, или даже больше, то мы бы усталь копировать, да и могли бы сделать ошибку. Вместо примитивного копирования используются циклы.
Общее устройство такое:
for (счётчик; условие остановки; изменение счётчика) {
// код, который нужно повторять
}
Перепишем пример с пятью "Hello, World!" с использованием новых знаний:
for (let i = 0; i < 5; i++) { // i++ эквивалентно i = i + 1
console.log("Hello, world!");
}
Вышло короче.
В цикле удобно работать с массивами:
let nums: Array<number> = [1, 2, 3, 4, 5];
for (let i = 0; i < 6; i++) {
console.log(nums[i] % 3);
}
Мы получили остатки от деления чисел из массива nums
на 3
. Откуда взялся NaN
? Обратите внимание, на условие остановки цикла. В нём есть ошибка, мы вышли за пределы массива.
Чтобы этого избежать можно сделать хитрее:
let nums: Array<number> = [1, 2, 3, 4, 5];
for (let i = 0; i < nums.length; i++) {
console.log(nums[i] % 3);
}
Вместо явного указания количества итераций мы попросили программу саму посмотреть количества элементов в массиве с помощью свойства массива length
.
Задание: напишите программу, которая для списка температур выводит индекс и значение температур, которые больше
37.0
.
Решение можно оформлять здесь
Мы избавились от излишнего дублирования с помощью циклов. Но представьте, что если нам понадобилось получать значения периметра для нескольких прямоугольников. Неужели нам придётся писать формулу для расчёта периметра и проверку ширины с высотой каждый раз? Конечно же нет. Для этого существуют функции. Функции позволяют определить блок кода, который можно выполнять несколько раз, в удобном месте.
Как выглядит объявление и вызов функции:
function названиеФункции(аргумент1: Тип1, аргумент2: Тип2): типРезультата {
/*
тело функции
*/
return результат // возврат результата из функции, чтобы можно было, например, присвоить переменной
}
Давайте считать периметры в любом месте:
function calculatePerimeter(w: number, h: number) : number | string { // определение функции
if (w > 0 && h > 0) {
return 2 * (w + h);
} else {
return "Некорректная ширина или высота!"
}
}
let width = 7;
let height = 14;
let perimeter = calculatePerimeter(width, height); // вызов функции
console.log(perimeter);
console.log(calculatePerimeter(7, 14));
console.log(calculatePerimeter(100, 100));
console.log(calculatePerimeter(100, 100));
console.log(calculatePerimeter(-100, 100));
Задание: Дан массив ширин и высот прямоугольников. Для каждого вывести площадь и периметр.
Решение можно оформлять здесь
Возвращаясь к тому, чем же является console.log()
. console
-- переменная (она глобальная, она определяется не нами), в которой хранится объект, для которого определена функция log
. Как делать такие объекты, которые позволяют таким образом предоставлять функции, мы разберёмся в следующих частях.
Структурное программирование — парадигма программирования, в основе которой лежит представление программы в виде иерархической структуры блоков.
Блок — логически сгруппированный набор идущих подряд инструкций в исходном коде программы
Алгоритм -- совокупность точно заданных правил решения некоторого класса задач или набор инструкций, описывающих порядок действий исполнителя для решения определённой задачи.
Любой исполняемый алгоритм может быть преобразован к структурированному виду, то есть, такому виду, когда ход его выполнения определяется только при помощи трёх структур управления:
1. последовательной (sequence) -- объявление, присваивание и другие операции над переменными; определение и вызов функций;
2. ветвлений (selection) -- те самыеif
,else
,switch-case
;
3. циклов (iteration) -- те самыеfor
,while
.
Это утверждение носит название Теорема Бёма — Якопини.
На основании него с полной уверенностью можно сказать, что у вас есть все инструменты, чтобы реализовать любой алгоритм!