Как дополнить методы сервера Hapi.js при использовании TypeScript?

TLDR; Не очень необходимо, но, вероятно, поможет в долгосрочной перспективе, и это более точно.

ПРИМЕЧАНИЕ. Многое редактировалось, поскольку мой предыдущий ответ был смущенно написан и имел некоторые ошибки, которые я пропустил в моей спешке, чтобы ответить. Спасибо тем, кто указал на некоторые вопиющие ошибки.

В принципе, для правильного подключения к подклассу в Javascript. Когда мы подклассом, мы должны сделать некоторые напуганные вещи, чтобы убедиться, что прототипная делеция работает правильно, включая перезапись объекта prototype. Перезапись объекта prototype включает в себя constructor, поэтому нам нужно исправить ссылку.

Давайте быстро рассмотрим, как работают «классы» в ES5.

Допустим, вы имеют конструкторскую функцию и ее прототип:

//Constructor Function
var Person = function(name, age) {
  this.name = name;
  this.age = age;
}

//Prototype Object - shared between all instances of Person
Person.prototype = {
  species: 'human',
}

Когда вы вызываете конструктор для создания экземпляра, скажем Adam:

// instantiate using the 'new' keyword
var adam = new Person('Adam', 19);

Ключевое слово new вызывается с помощью «Человек» 'в основном будет запускать конструктор Person с несколькими дополнительными строками кода:

function Person (name, age) {
  // This additional line is automatically added by the keyword 'new'
  // it sets up the relationship between the instance and the prototype object
  // So that the instance will delegate to the Prototype object
  this = Object.create(Person.prototype);

  this.name = name;
  this.age = age;

  return this;
}

/* So 'adam' will be an object that looks like this:
 * {
 *   name: 'Adam',
 *   age: 19
 * }
 */

Если мы console.log(adam.species), поиск не будет выполняться на экземпляре adam и будет искать прототипную цепочку для его .prototype, который есть Person.prototype - и Person.prototype , имеет свойство a .species, поэтому поиск будет успешным на Person.prototype. Затем он будет записывать 'human'.

Здесь Person.prototype.constructor будет правильно указывать на Person.

Итак, теперь интересная часть - так называемое «подклассификация». Если мы хотим создать класс Student, являющийся подклассом класса Person с некоторыми дополнительными изменениями, нам нужно убедиться, что Student.prototype.constructor указывает на точность для ученика.

Это не делается само по себе. При подклассе код выглядит следующим образом:

var Student = function(name, age, school) {
 // Calls the 'super' class, as every student is an instance of a Person
 Person.call(this, name, age);
 // This is what makes the Student instances different
 this.school = school
}

var eve = new Student('Eve', 20, 'UCSF');

console.log(Student.prototype); // this will be an empty object: {}

Вызов new Student() здесь возвращает объект со всеми требуемыми свойствами. Здесь, если мы проверим eve instanceof Person, он вернется false. Если мы попытаемся получить доступ к eve.species, он вернет undefined.

Другими словами, нам нужно связать делегирование, чтобы eve instanceof Person возвращало true и чтобы экземпляры делегата Student правильно Student.prototype, а затем Person.prototype.

НО, так как мы вызываем его с ключевым словом new, помните, что добавляет этот призыв? Он назовет Object.create(Student.prototype), как мы установили это делегиальное отношение между Student и Student.prototype. Обратите внимание, что прямо сейчас Student.prototype пуст. Таким образом, при поиске .species экземпляр Student потерпит неудачу, поскольку он делегирует только Student.prototype, а свойство .species не существует на Student.prototype.

Когда мы присваиваем Student.prototype Object.create(Person.prototype), сам Student.prototype делегирует Person.prototype, и поиск eve.species вернет human, как мы ожидаем. Предположительно, мы хотели бы, чтобы он наследовал от Student.prototype AND Person.prototype. Поэтому нам нужно все это исправить.

/* This sets up the prototypal delegation correctly 
 *so that if a lookup fails on Student.prototype, it would delegate to Person's .prototype
 *This also allows us to add more things to Student.prototype 
 *that Person.prototype may not have
 *So now a failed lookup on an instance of Student 
 *will first look at Student.prototype, 
 *and failing that, go to Person.prototype (and failing /that/, where do we think it'll go?)
*/
Student.prototype = Object.create(Person.prototype);

Теперь делегация работает, но мы переписываем Student.prototype с помощью функции Person.prototype. Поэтому, если мы назовем Student.prototype.constructor, он будет указывать на Person вместо Student. Вот почему мы должны это исправить.

// Now we fix what the .constructor property is pointing to    
Student.prototype.constructor = Student

// If we check instanceof here
console.log(eve instanceof Person) // true

В ES5 наше свойство constructor является ссылкой, которая ссылается на функцию, которую мы написали с намерением стать «конструктором». Помимо того, что дает нам ключевое слово new, конструктор в противном случае является «простой» функцией.

В ES6 constructor теперь встроен в способ, которым мы пишем классы - как в, он предоставляется как метод, когда мы объявляем класс. Это просто синтаксический сахар, но он предоставляет нам некоторые удобства, такие как доступ к super, когда мы расширяем существующий класс. Поэтому мы должны написать вышеприведенный код следующим образом:

class Person {
  // constructor function here
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  // static getter instead of a static property
  static get species() {
    return 'human';
  }
}

class Student extends Person {
   constructor(name, age, school) {
      // calling the superclass constructor
      super(name, age);
      this.school = school;
   }
}
1
задан Harshal Patil 16 January 2019 в 08:57
поделиться