简体   繁体   English

在方法调用上创建新的 this

[英]Create new this on method call

This may be a stupid question, but is it possible to create a new this on a method call of a class?这可能是一个愚蠢的问题,但是是否可以在类的方法调用上创建一个新的 this ? Eg:例如:

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?

Maybe this is too hard to understand, sorry.也许这太难理解了,抱歉。

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

This would be the code where it uses the same this variable - this doesn't fit what I wanted but is what I currently have.这将是它使用相同 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

This example would obviously cause an error because the return value of a() a number, not something to use a method on again.这个例子显然会导致错误,因为 a() 的返回值是一个数字,而不是再次使用方法的东西。 Please let me know if I need to explain further -- I'm having some struggle explaining it properly.如果我需要进一步解释,请告诉我 - 我很难正确解释它。

On my solution, I decided to create two variables to hold the values of each method.在我的解决方案中,我决定创建两个变量来保存每个方法的值。 ( https://jsbin.com/wozuyefebu/edit?js,console ) ( https://jsbin.com/wozuyefebu/edit?js,console )

The a() method will return a number if the isSingle parameter is set to true .如果isSingle参数设置为truea()方法将返回一个数字。 If not, it will return the this object, allowing you to chain the b() method.如果没有,它将返回this对象,允许您链接b()方法。 This is might be a hack but I believe it solves your problem.这可能是一个黑客,但我相信它可以解决您的问题。

I write about Javascript and web development on my blog :) https://changani.me/blog我在我的博客上写了关于 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 ) ( https://jsbin.com/wozuyefebu/edit?js,console )

If you want to be able to invoke methods on return value of methods, then, you should return this from those methods.如果您希望能够在方法的返回值上调用方法,那么您应该从这些方法中返回this However, you will need an additional method, say value() to actuall get the result of sum.但是,您将需要一个额外的方法,比如value()来实际获得 sum 的结果。

A possible way is show below.一种可能的方法如下所示。

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

If the intention is that foo.a(1).b(2) changes foo , or if you don't mind changing foo , the other answers here work.如果意图是foo.a(1).b(2)改变foo ,或者如果你不介意改变foo ,这里的其他答案有效。

But if you only want foo.a(1).b(2) to return 3 without modifying foo , then you need to return a new Foo .但是如果你希望foo.a(1).b(2)返回3而不修改foo ,那么你需要返回一个新的Foo

Now, if you really hell bent on having console.log() print 3 rather than something like Foo { value: 3 } , you can also customize inspect() (given that the question is tagged with node.js ).现在,如果你真的一心想console.log()打印3而不是像Foo { value: 3 }这样的东西,你还可以自定义inspect() (假设问题是用node.js标记的)。

All together:全部一起:

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

Output:输出:

0
3
0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 调用模式方法而无需使用Nodejs / Mongoose创建新的Model对象 - Call schema method without create a new Model object with Nodejs/Mongoose 使用API​​调用创建新数据库 - Create new database with API call BrainTreePayments创建新的付款方式 - BrainTreePayments create new payment method 流星新建:RangeError:超出最大调用堆栈大小 - Meteor create new: RangeError: Maximum call stack size exceeded Mongoose - 使用post方法创建一个新的空集合 - Mongoose - use a post method to create a new empty collection 我应该在每个类方法中创建一个新的Promise吗? - Should I create a new Promise in each class method? 调用方法的方法(如果存在) - Call the method of a method if it exists 在Node.js中调用Object.create(new EventEmitter)是什么意思 - What does it mean to call Object.create(new EventEmitter) in Node.js 通过node.js命令行界面报告创建azure hdinsight“无法调用未定义的方法'filter'” - Create azure hdinsight by node.js command line interface report “Cannot call method 'filter' of undefined” 使用 loopback-connector-remote 在另一个环回服务中调用自定义方法不会创建正确的 URL - Using loopback-connector-remote to call custom method in another loopback service doesn't create correct URL
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM