Использование конструктора в TypeScript
В TypeScript конструктор играет ключевую роль в объектно-ориентированном программировании. В этой статье мы разберем его тонкости. Идеально подходит для разработчиков, желающих отточить свои навыки TypeScript.
Создание конструктора класса
Метод-конструктор в классе должен иметь имя «constructor» . Класс может иметь только одну реализацию метода конструктора .
Метод конструктора вызывается каждый раз, когда мы создаем экземпляр класса с помощью нового оператора.
Он всегда возвращает вновь созданный объект. Ниже приведен пустой класс Person с конструктором метода. Метод конструктора печатает Constructor is called
. Как вы можете видеть, каждый раз, когда мы выполняем оператор, new Person()
сообщение выводится на консоль.
class Person { constructor() { console.log("Constructor is called") } } let p1= new Person() //contructor is called let p2= new Person() //contructor is called
Метод конструктора создает экземпляр объекта со свойством, определенным в классе. Мы можем получить доступ к текущему экземпляру, используя this
внутри конструктора. После завершения функция конструктора возвращает новый объект.
Параметры метода конструктора
Конструкторы похожи на обычные функции в том смысле, что они также принимают параметры. Нам нужно передавать значения параметров при создании нового экземпляра класса.
Функция-конструктор в следующем примере принимает два аргумента. Мы используем this
ключевое слово ' ', чтобы получить текущий экземпляр класса и инициализировать его свойства, используя эти параметры.
class Person { firstName:string; lastName:string; constructor(fName:string, lName:string) { this.firstName=fName; this.lastName=lName; } }
Мы создаем экземпляр класса, вызывая new
оператор класса Person
. В аргументе мы передадим значения для fName
& lName
аргументов. Будет new Person
вызывать функцию-конструктор, связанную с классом, Person
вместе с аргументами.
let p= new Person("Jon","Snow") console.log(p) //Person: { "firstName": "Jon", "lastName": "Snow" }
Параметр в конструкторе здесь не является обязательным. Это означает, что при создании экземпляра класса вы должны передать значения всех аргументов конструктору. Если вы не передадите все параметры, это приведет к ошибке компилятора.
let p= new Person("Jon") //Expected 2 arguments, but got 1.
В следующем примере мы добавили несколько операторов console.log в метод конструктора, чтобы отображать значение this
свойства ' ' после каждого оператора.
class Person { firstName:string; lastName:string; constructor(fName:string, lName:string) { console.log("contructor is called") console.log(this) this.firstName=fName; console.log(this) this.lastName=lName; console.log(this) } } let p= new Person("Jon","Snow") //"contructor is called" //Person: {} //Person: { "firstName": "Jon"} //Person: { "firstName": "Jon", "lastName": "Snow"}
Свойства параметров конструктора
Свойства параметров конструктора (или синтаксис сокращенного обозначения свойства) предлагают специальный сокращенный синтаксис для преобразования параметров функции-конструктора в свойства. Мы можем сделать это, добавив к параметру конструктора префикс одного из модификаторов видимости (т.е. public
, private
,protected
или readonly
). Результирующее поле получает эти модификаторы.
В этом примере мы создали поля firstName
& lastName
вручную.
class Person { firstName:string; lastName:string; constructor(firstName:string, lastName:string) { this.firstName=firstName; this.lastName=lastName; } }
Вместо этого мы можем поставить перед параметрами конструктора модификатор public . Typescript автоматически создает для нас свойства.
class Person { constructor(public firstName:string, public lastName:string) { } } let p = new Person("Jon", "Snow"); console.log(p) //Person: { "firstName": "Jon", "lastName": "Snow" }
Передача значений по умолчанию в методе конструктора
Мы также можем передать значение по умолчанию методу конструктора. В этом примере x
свойства y
инициализируются значениями 10 и 20, если мы не передаем никаких значений при создании нового экземпляра.
class Point { x: number; y: number; constructor(x = 10, y = 20) { this.x = x; this.y = y; } } //Using default Values let p1 = new Point(); console.log(p1) //Point: { "x": 10, "y": 20 } let p2 = new Point(100,200); console.log(p2) //Point: { "x": 100, "y": 200 }
Функции-конструкторы в производном классе
Производный класс должен вызвать конструктор родительского класса (базового класса). Мы делаем это, вызывая super
метод. Мы должны вызвать суперметод, прежде чем использовать this
переменную.
В этом примере класс Employee расширяет Person класс и добавляет собственное свойство designation. Здесь Employee класс должен вызвать конструктор класса Person. Для этого мы используем super функцию. Суперфункцию необходимо вызывать с параметрами конструктора Person. class Person { firstName:string; lastName:string; constructor(firstName:string, lastName:string) { this.firstName=firstName; this.lastName=lastName; } } class Employee extends Person { designation:string; constructor(firstName:string, lastName:string, designation:string) { super(firstName,lastName) // call parent class constructor this.designation=designation; } } let e = new Employee("Jon","Snow","Manager") console.log(e) //Employee: { "firstName": "Jon", "lastName": "Snow", "designation": "Manager" }
Вызовите метод super перед обращением к «this» или перед возвратом из производного конструктора. Попытка доступа к переменной this приведет к ошибкам как во время компиляции, так и во время выполнения (« super» необходимо вызвать перед доступом к «this» в конструкторе производного класса »).
class Employee extends Person { designation:string; constructor(firstName:string, lastName:string, designation:string) { //Both compiler and run time error console.log(this) //'super' must be called before accessing 'this' in the constructor of a derived class. super(firstName,lastName) // call parent class constructor this.designation=designation; } }
Отказ от вызова super
в производном классе также приведет к ошибке компилятора. « Конструкторы для производных классов должны содержать «супер» вызов ».
class Employee extends Person { designation:string; constructor(firstName:string, lastName:string, designation:string) { this.designation=designation; } } //Constructors for derived classes must contain a 'super' call.
Класс без конструктора
Вы можете создать класс без метода конструктора. В таких случаях JavaScript (не TypeScript) автоматически использует конструктор по умолчанию.
Конструктор по умолчанию — пустой конструктор.
constructor() { }
Но если класс является производным классом, то конструктор по умолчанию выглядит так, как показано ниже.
constructor(...args) { super(...args); }
Несколько методов конструктора
Класс может иметь только одну реализацию метода конструктора. Наличие более одной функции-конструктора приведет к ошибке. Вы не можете использовать конструктор имени в методе получения или установки.
Но мы можем воспользоваться перегрузкой функции для создания нескольких сигнатур перегрузки функции-конструктора.
В этом примере класс person имеет только одно свойство name
, т.е. Мы хотели бы создать экземпляр класса либо с помощью a, name
либо с помощью firstName
& lastName
.
Для этого сначала нам нужно создать две сигнатуры функций-конструкторов (сигнатуры перегрузки), по одной для каждого варианта использования. Затем фактическая функция-конструктор (функция реализации), в которой вы пишете реализацию.
class Person { name:string; constructor(name:string); //constructor function signature 1 constructor(firstName:string,lastName:string); //constructor function signature 2 constructor(name:string, lastName?:string) { //actual constructor function if (lastName) { this.name=name+" "+lastName } else { this.name=name; } } } let p = new Person("Jon", "Snow"); console.log(p) //Person: { "name": "Jon Snow" } p = new Person("Samwell Tarly"); console.log(p) //Person: { "name": "Samwell Tarly" }
Обратите внимание, что свойство параметра разрешено только в реализации конструктора. Например, добавление модификатора public к свойству name в сигнатуре функции конструктора приводит к ошибке компилятора.
class Person { constructor(public name:string); //Error constructor(firstName:string,lastName:string); constructor(name:string, lastName?:string) { if (lastName) { this.name=name+" "+lastName } else { this.name=name; } } } //<strong>parameter property</strong> is only allowed in a constructor implementatio
Вы можете префикс модификатора public к свойству name только в функции реализации конструктора.
class Person { constructor(name:string); constructor(firstName:string,lastName:string); constructor(public name:string, lastName?:string) { //ok if (lastName) { this.name=name+" "+lastName } else { this.name=name; } } }