【问题标题】:Create new this on method call在方法调用上创建新的 this
【发布时间】:2020-02-08 13:00:43
【问题描述】:

这可能是一个愚蠢的问题,但是否可以在类的方法调用上创建一个新的 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;
  }
}

这将是它使用相同 this 变量的代码 - 这不符合我想要的但是我目前拥有的。

// 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

这个例子显然会导致错误,因为 a() 的返回值是一个数字,而不是再次使用方法的东西。 如果我需要进一步解释,请告诉我——我很难正确解释。

【问题讨论】:

  • 只有class Foo { ... },不是class Foo() { ... }。从class Foo() 中删除您的()

标签: node.js oop method-chaining


【解决方案1】:

如果意图是 foo.a(1).b(2) 更改 foo,或者如果您不介意更改 foo,则此处的其他答案有效。

但是如果你希望foo.a(1).b(2)返回3而不修改foo,那么你需要返回一个新的Foo

现在,如果您真的一心想要使用console.log() 打印3 而不是Foo { value: 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

【讨论】:

    【解决方案2】:

    在我的解决方案中,我决定创建两个变量来保存每个方法的值。 (https://jsbin.com/wozuyefebu/edit?js,console)

    如果isSingle 参数设置为truea() 方法将返回一个数字。如果没有,它将返回this 对象,允许您链接b() 方法。这可能是一个黑客,但我相信它可以解决你的问题。

    我在我的博客上写了关于 Javascript 和 Web 开发的文章 :) 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,console)

    【讨论】:

      【解决方案3】:

      如果您希望能够根据方法的返回值调用方法,那么您应该从这些方法中返回this。但是,您将需要一个额外的方法,例如 value() 来实际得到 sum 的结果。

      一种可能的方法如下所示。

      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());

      【讨论】:

        猜你喜欢
        • 2023-02-07
        • 1970-01-01
        • 2019-11-17
        • 1970-01-01
        • 2018-03-28
        • 1970-01-01
        • 2010-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多