Создать новый метод при вызове метода - PullRequest
0 голосов
/ 08 февраля 2020

Это может быть глупый вопрос, но возможно ли создать новое this при вызове метода класса? Например:

const foo = new Foo();
console.log(foo.a(1).b(2));
// for example, outputs 3 (1+2)
// the a method will create a new namespace and attach 1 to it, and b will use that new namespace
console.log(foo.b(2));
// this will result in an error, as there is no new namespace from the a method anymore, so b cannot add to anything?

Возможно, это слишком сложно понять, извините.

class Foo {
  a(number) {
    this.a = number;
    return this;
  }
  b(number) {
    return this.a + number;
  }
}

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

// pseudo
class Foo {
  a(number) {
    const uniqueVariable = number
    return uniqueVariable
    // it'll somehow pass the number from this method to the next method
  }
  // where it can be used with the second method's input
  b(uniqueVariable, number) {
    return uniqueVariable + number
  }
}
foo.a(1).b(2) = 3

Этот пример, очевидно, вызовет ошибку, потому что возвращаемое значение () число, а не что-то, чтобы использовать метод снова. Пожалуйста, дайте мне знать, если мне нужно объяснить дальше - у меня возникли трудности с объяснением этого должным образом.

Ответы [ 3 ]

0 голосов
/ 08 февраля 2020

Если вы хотите иметь возможность вызывать методы для возвращаемого значения методов, вы должны вернуть this из этих методов. Однако вам понадобится дополнительный метод, скажем, value(), чтобы получить результат суммирования.

Возможный способ показан ниже.

class Foo {
  _a = 0;
  _b = 0;
  
  a(number) {
    this._a = number;
    return this;
  }
  
  b(number) {
    this._b = number;
    return this;
  }
  
  value() {
    return this._a + this._b;
  }
}

const foo = new Foo();
console.log(foo.a(1).b(2).value());
console.log(foo.b(5).value());
0 голосов
/ 08 февраля 2020

Если предполагается, что foo.a(1).b(2) изменит foo, или если вы не возражаете против изменения foo, другие ответы здесь сработают.

Но если вы только хотите foo.a(1).b(2) вернуть 3 без изменения foo, тогда вам нужно вернуть новый Foo.

Теперь, если вы действительно одержимы желанием console.log() вместо Foo { value: 3 } выведите 3, вы также можете настроить inspect() (учитывая, что вопрос помечен node.js).

Все вместе:

const util = require('util');

class Foo {
    constructor(value) {
        this.value = value || 0;
    }

    add(value) {
        return new Foo(this.value + value);
    }

    a(value) {
        return this.add(value);
    }

    b(value) {
        return this.add(value);
    }

    [util.inspect.custom]() {
        return this.value;
    }
}

const foo = new Foo();
console.log(foo);
console.log(foo.a(2).b(1));
console.log(foo);

Выход:

0
3
0
0 голосов
/ 08 февраля 2020

В своем решении я решил создать две переменные для хранения значений каждого метода. (https://jsbin.com/wozuyefebu/edit?js, консоль )

Метод a() возвращает число, если для параметра isSingle установлено значение true. Если нет, он вернет объект this, что позволит вам связать метод b(). Это может быть взломом, но я верю, что это решит вашу проблему.

Я пишу о Javascript и веб-разработке в моем блоге :) https://changani.me/blog

class Foo {
  constructor() {
    this.aValue = 0;
    this.bValue = 0;
  }

  /**
  * @param {Number} value
  * @param {Boolean} isSingle
  * @returns {Object/Number}
  */
  a(value = 0, isSingle = false) {
    this.aValue = value;
    return isSingle ? this.aValue : this;
  }

  /**
  * @param {Number} value
  * @returns {Number}
  */
  b(value = 0) {
    this.bValue = this.aValue + value;
    return this.bValue;
  }
}

const x = new Foo();

console.log("Should return 3: ", x.a(2).b(1));
console.log("Should return an 2: ", x.a(2, true));
console.log("Should return an instance of the object: ", x.a(2));
console.log("Should return 1: ", x.b(1));
console.log("Should return 0: ", x.a().b());

(https://jsbin.com/wozuyefebu/edit?js, консоль )

...