Использование конструктора в 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;
    }
  }
}