Как динамически сопоставить аргументы конструктора класса javascript со свойствами экземпляра - PullRequest
2 голосов
/ 14 января 2020

Я создаю приложение Node.js (Node v10.11.0) и хочу сделать это в OOP без использования Typescript. Итак, я построил несколько классов, таких как:

class Component {
  constructor(param1, param2, param3) {
    this.param1= param1;
    this.param2 = param2;
    this.param3 = param3;
  }
}

Мне было интересно, есть ли способ в javascript для автоматического сопоставления аргументов конструктора без записи this.param1 = param1 для каждого аргумента конструктора.

Я уже пытался запустить объект arguments с чем-то вроде этого:

constructor(param1, param2, param3) {
  Array.from(arguments).forEach(arg => {
    this[arg] = arg;
  }
}

, но это не работает. Результат такого подхода:

console.log(new Component("arg1", "arg3", "arg3"))

// Component { arg1: "arg1", arg2: "arg2", arg3: "arg3" }
// I want to have this:
// Component { param1: "arg1", param2: "arg2", param3: "arg3" }

Ответы [ 2 ]

5 голосов
/ 14 января 2020

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

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

constructor(args) {
    Object.assign(this, args);
}

, который вы называете так:

new Component({param1: "arg1", param2: "arg2", param3: "arg3"});

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

Третий вариант - принять параметр rest:

constructor(...args) {
    ["param1", "param2", "param3"].forEach((name, index) => {
        this[name] = args[index];
    });
}

, который вы вызываете обычным способом, но опять же, пока он субъективен. , для меня читаемость ухудшается.


Как примечание, как я думаю, вы, вероятно, знаете, TypeScript имеет эту функцию. Сейчас все чаще используется TypeScript (который компилируется в JavaScript для использования в браузерах). TypeScript не привязан к Angular, его можно использовать практически с любым каркасом (или без него).

Например, в TypeScript:

// TypeScript
class Component {
    constructor(
        public param1: string,
        public param2: string,
        public param3: string
    ) {
    }
}

В коде нет необходимости вообще, конструктор TypeScript автоматически присваивает эти значения параметров этим свойствам publi c. (Вы также можете использовать private или protected.)

1 голос
/ 14 января 2020

Поскольку вы передаете объект в качестве параметра, вы можете использовать Object.keys

Пример кода фрагмента

class Component {
  constructor(args) {
    Object.keys(args).forEach(argKey => this[argKey] = args[argKey])
  }
}

let a = new Component({param1: "arg1", param2: "arg2", param3: "arg3"})


console.log(a)
...