Есть ли лучший способ передать параметры класса внешней функции?

#node.js #typescript

#node.js #typescript

Вопрос:

Я создал модуль nodejs, написанный на typescript, который работает нормально, но я не особенно доволен методом, который я использовал для передачи объявленных параметров класса внешним функциям (функции, объявленные вне области видимости класса). Есть ли лучший способ сделать это, не передавая переменные одну за другой во «внешнюю» функцию?

Я знаю, что мог бы переместить функцию fooFunc в класс, но я избегаю этого, потому что я не хочу, чтобы эта функция была доступна для кода, который использует результирующий модуль (я только хочу, чтобы check() был доступен) из-за экспортируемого класса.

 export class Foo {

   private readonly a: number;

   constructor(a: number) {
      this.a = a;
   }

   async check() {
      fooFunc(this.a);
   }

}

async function fooFunc(a: number) {
   console.log(a);
}
  

Ответ №1:

Вы могли .call fooFunc бы использовать, так что this inside fooFunc ссылается на foo экземпляр, поэтому нет необходимости передавать переменные экземпляра в fooFunc :

 export class Foo {

   readonly a: number;

   constructor(a: number) {
      this.a = a;
   }

   async check() {
      fooFunc.call(this);
   }

}

async function fooFunc(this: Foo) {
    console.log(this.a);
}
  

( a конечно, этого не должно быть private )

Комментарии:

1. Я думаю, что это самый элегантный ответ, поскольку он не добавляет дополнительной сложности для решения проблемы, предполагая, конечно, что это также наиболее эффективный, поскольку производительность является ключевой для этого модуля.

Ответ №2:

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

 abstract class ParamCheck {
    private readonly args: any[];

    constructor(...args) {
        this.args = args;
    }

    async check() {
        fooFunc(this.args);
    }
}

class Foo extends ParamCheck {
    constructor(private a: number, private b: number) {  
        super(a, b);
    }
}

async function fooFunc(...args) {
    console.log(args);
}

new Foo(1, 2).check();
  

Ответ №3:

В качестве альтернативы вы могли бы рассмотреть возможность создания объекта foo путем передачи реализации fooFunc в конструктор. Что-то вроде этого:

 type CheckFunc = (n: number) => any;

export class Foo {

   private readonly a: number;
   private readonly checkFunc: CheckFunc; 

   constructor(a: number, checkFunc: CheckFunc) {
      this.a = a;
      this.checkFunc = checkFunc;
   }

   async check() {
      this.checkFunc(this.a);
   }

}

///////

async function fooFunc(a: number) {
   console.log(a);
}

const foo = new Foo(1, fooFunc);
  

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