如何将链函数从一个类添加到另一个类?
Posted
技术标签:
【中文标题】如何将链函数从一个类添加到另一个类?【英文标题】:How to add chain functions from one class to another? 【发布时间】:2020-02-26 01:04:41 【问题描述】:我正在尝试在 JS 中开发一个供个人使用的游戏引擎。我想让我的引擎能够使用不同类的元素。我试图解决的一个这样的问题是将方法从一个类(比如一个链接函数的数学类)链接到我的主函数。
这是我希望它看起来像的示例:
let game = new Engine()
game.operator(5).sum(3).divide(2)
这可能是我的代码中的内容,尽管我不确定该怎么做。
class Engine
constructor()
//Set up engine here
/* This is where I am unsure how to link the following operator class to this one.
* Do I put it here in constructor or ...
*/
/* ... do I put it here? (Or not in this class at all?)
*
* This is what I tried doing as a function
*
* operator(input)
* let op = new Operator(input);
*
*/
class Operator
/*The following class is different than the one I am using, but follows similar syntax:
* Basic usage: operator(5).sum(3, 4) => Should output 12
* How the class works is mostly irrelevant, just know it chains methods.
*/
constructor(input)
this.input = input;
this.answer = this.input;
sum()
let a = arguments[0]
for(var i = 1; i < arguments.length; i++)
a += arguments[i];
this.answer += a;
return this;
divide()
let a = arguments[0];
for(var i = 1; i < arguments.length; i++)
a *= arguments[i];
this.answer /= a;
return this;
如何让一个类能够链接不同类的方法?
【问题讨论】:
Engine
中的 operator
函数可以返回您在那里构建的 Operator 对象。很高兴您可以在单个语句中链接事物,但不要过度。
【参考方案1】:
链接模式是让实例保持链状态,并提供返回链状态的“值”方法。为了在两个类之间链接,我想我会包含一个特殊的 value 方法,它返回另一个类的实例。 (为了保持读者的导向,将其命名为表明类型更改的名称)...
class ObjectA
constructor(string)
this.chainValue = string
this.string = string
transformA()
this.chainValue = this.chainValue.toUpperCase()
return this
transformB()
this.chainValue = this.chainValue + "bar"
return this
// the regular value method
get value()
return this.chainValue
// like the value method, but named to explicitly return MyNumber
get numberValue()
return new MyNumber(this.value.length)
class MyNumber
constructor(int)
this.chainValue = int
this.int = int
add(n)
this.chainValue += n
return this
get value()
return this.chainValue
let a = new ObjectA("foo")
console.log(
a
.transformB() // append "bar"
.transformA() // convert to upper case
.numberValue // return a number (arbitrarily, the length of the chain state)
.add(12) // add 12
.value // expect 18
)
【讨论】:
这也很好用!这输出与其他答案相同,但不需要代理。【参考方案2】:您可以为此目的使用代理。
class Engine
operator()
// code
console.log('call operator')
class Operator
sum()
// code
console.log('call sum')
divide()
console.log('call divide')
class SuperOperator
negate()
console.log('call negate')
const operator = new Operator();
const superOperator = new SuperOperator();
const engine = new Engine();
const objectsToChainFrom = [
engine,
operator,
superOperator,
];
// create helper function for proxy
function wrapper(originalMethod, ctx)
return function ()
originalMethod.apply(ctx, arguments);
// return proxy;
return this;
var proxy1 = new Proxy(objectsToChainFrom,
get(target, methodToCall, receiver)
const objectWithMethod = target.find(el => el[methodToCall]);
return wrapper(objectWithMethod[methodToCall], objectWithMethod)
);
proxy1
.sum()
.operator()
.divide()
.negate()
【讨论】:
以上是关于如何将链函数从一个类添加到另一个类?的主要内容,如果未能解决你的问题,请参考以下文章