Классы в JavaScript появились только после выхода стандарта ES6 (EcmaScript 2015), привнесшего массу нововведений в синтаксис языка, хотя ключевое слово class было зарезервировано в JavaScript с момента его создания. С точки зрения подхода к созданию однотипных объектов, создание классов очень облегчило подход к записи кода, с точки же зрения работы самого языка JavaScript поменялось немного, т.к. классы все равно базируются на прототипах.

Именно по последней причине классы еще называют синтаксическим сахаром - т.е. красивой оберткой над тем, что было заложено в ядро JavaScript с самого начала, а именно - создание функций, которые являлись конструктором для экземпляров определенного класса и основывались на использовании определенных внутри этой функции свойств и методов. Тем не менее создание классов сделало этот язык понятней для программистов на Java или C# и упростило сам синтаксис создания объектов как экземпляров класса.

Синтаксис класса в JavaScript

Во-первых, как для любой переменной или функции, для класса нужно задать имя после ключевого слова class. Оно записывается с большой буквы и после него идут фигурные скобки (тело класса), в которых будут находится все функции (методы) этого класса.

Основной функцией в классе является конструктор (constructor()). Именно он вызывается при создании экземпляра класса строкой вида:

В классе может быть только один конструктор, т.е. метод с именем constructor вы можете объявить однократно.

Достаточно часто внутрь функции-конструктора передаются некоторые переменные, которые в становятся свойствами этого класса и затем используются в различных его методах. Например, нам необходимо создать класс, который будет выводить часы, минуты и секунды. Мы не будем использовать в нем методы объекта Date, но он позволит нам манипулировать временем. Назовем этот класс Clock и используем в качестве свойств то, что нам надо вывести.

В конструктор класса мы передаем начальные значения часов, минут и секунд. А функция showClock() выведет нам все переданные значения в виде строки с разделением с помощью двоеточия.

Обратите внимание на то, что внутри класса все свойства записываются с помощью ключевого слова this, которое указывает на текущий объект класса Clock. Запись функции-конструктора в классе можно заменить такой функцией:

Обычно конструкторы ничего не возвращают явно. Их задача – записать все необходимые свойства в this, а иногда и вызвать методы, чтобы мы могли пользоваться экземпляром класса.

Обратите внимание на то, что классы всегда нужно объявлять ДО их использования, в отличие от функций. Объявление функции (function declaration) совершает подъём (hoisted), т.е. интерпретатор знает о ее существовании до момента вызова, где бы она не была объявлена, в то время как объявление класса (class declaration) — нет. Поэтому сначала нужно объявить класс и только потом создавать его экземпляры во избежание ошибок типа ReferenceError:

Class geclaration Reference error

Поэтому мы объявляем внизу (строка 11)  переменную clock1, которая является экземпляром созданного нами класса Clock. Результат:

Мы можем вывести с помощью нашего класса текущее время, воспользовавшись встроенным в JavaScript классом Date и его методами.

Результат:

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

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

Добавление методов класса Clock

Поскольку предыдущий пример показал, что класс требует доработки, изменим его таким образом:

В функции-конструкторе мы вызываем 3 функции для проверки корректности переданных параметров для реальных часов. Например, функция checkHours проверяет значение this.hour и в том случае, если оно больше 23, записывает остаток от деления на 24 в свойство this.hour и возвращает его в качестве значения. Для минут и секунд функции будут похожи и в их задачу будет входить определение того, а превышает ли значение минут (секунд) цифру 59, и если это так, то остаток от деления мы будем записывать в this.min (this.sec), а целочисленное значение от деления на 60 добавлять к часам или минутам.

Результат создания экземпляра класса с параметрами new Clock(27, 122, 368) вернет нам уже совсем другие значения:

Надеюсь, вы обратили внимание на то, что все функции класса внутри него также вызываются с помощью ключевого слова this, которое в момент объявления переменной-экземпляра класса Clock, связано именно с этой переменной. Можно сказать, что this - это указание на переменную (объект), которая находится слева от точки, с помощью которой мы вызываем методы класса.

В классе Clock мы также добавили метод format, который выводит ноль перед числами до 10 в привычном нам формате часов : минут : секунд.

Использование внешней функции и собственных методов

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

Сам код класса также станет другим. Обратите внимание, что в том месте в функции showClock(), где мы вызываем внешнюю функцию randomColor(), мы уже не пишем this.randomColor(), т.к. эта функция не входит в методы класса Clock.

Мы добавили функции addHours(), addMin() и addSec(), каждая из которых принимает некоторое числовое значение, добавляет это значение к соответствующему свойству нашего класса, а затем проверяет его на правильность. Мы также поменяли вывод информации, добавив к времени поясняющий текст в функции showClock(). Смотрим на результат:

Добавляем интерактивности в класс

Наш класс все больше расширяется, но пока мы можем только изменять значения, передавая параметры в функцию. Намного интереснее было бы протестировать его, вводя данные в поля формы. Для начала нам нужно сделать html-разметку формы с полями типа number:

Измененный класс Clock с новой функцией showHTMLClock() для вывода сообщений в нужный html-элемент и функцией checkInputData(some), которая не позволяет отнимать время, передавая отрицательные значения и проверяет правильность ввода чисел, если вдруг вы захотите получить данные от пользователя методом prompt() или использовать текстовые поля вида <input type="text">. Кроме того, мы убрали из конструктора вызов функции showClock(), так как теперь мы будем добавлять информацию в нужный html-элемент с помощью showHTMLClock():

При обработке клика на кнопках, размещенных рядом с полями типа number, мы будем получать из их data-атрибутов название функции и тех единиц, которые мы изменяем. С помощью конструкции switch...case сможем вызвать нужную функцию.

Посмотрим на результат:

Экземпляры класса

Если заглянуть под капот нашего класса, то мы увидим, что все методы, которые мы объявили в классе, сейчас записаны в его свойстве __proto__, т.е. класс основан на прототипном наследовании. Это значит, что любой из экземпляров класса будет иметь доступ к любой из функций, в нем объявленных.

Методы класса Clock

Мы также можем увидеть, что сам класс Clock является функцией, т.к. представляет собой экземпляр класса Function, а любая переменная, объявленная нами ранее является экземпляром класса Clock:

Тем не менее, переменная clock6 не является экземпляром класса Function, т.к. представляет  собой объект, т.е. принадлежит к классу Object, который лежит в основе всех объектов JavaScript.

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

Ниже вы найдете несколько примеров классов с различными часами от одного автора - Jon Kantner. На его страничке на codepen.io таких примеров намного больше. Они интересны еще и с точки зрения визуальной реализации. Посмотрите код - возможно, вам понравится подход автора.

Пример 1

See the Pen #Clocktober Day 27: Wireframe by Jon Kantner (@jkantner) on CodePen.

Пример 2

See the Pen #Clocktober Day 29: Pie by Jon Kantner (@jkantner) on CodePen.

Пример 3

See the Pen #Clocktober Day 2: Scale by Jon Kantner (@jkantner) on CodePen.

Автор: Админ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *