我想有一个类我可以指定“ A的实例a1,当你需要值”时,你将调用B的特定实例b1的函数computeValue()。我需要指定此实例将使用哪个实例的方法。
到目前为止,我找到了两个解决方案:
eval()
解决方案:
class A {
constructor(funcToCall) {
this.funcToCall = funcToCall;
}
displayValue() {
console.log(eval(this.funcToCall));
}
}
class B {
constructor(value) {
this.value = value;
}
computeValue() {
return this.value;
}
}
var b1 = new B(1);
var a1 = new A("b1.computeValue()");
a1.displayValue();// Displays "1", okay
function.call()
解决方案:
class A {
constructor(funcToCall, instanceToCallItOn) {
this.funcToCall = funcToCall;
this.instanceToCallItOn = instanceToCallItOn;
}
displayValue() {
console.log(this.funcToCall.call(this.instanceToCallItOn));
}
}
class B {
constructor(value) {
this.value = value;
}
computeValue() {
return this.value;
}
}
var b1 = new B(1);
var a1 = new A(b1.computeValue, b1);
a1.displayValue(); // Displays "1", okay
所以对我来说,eval()
解决方案似乎很脏,而function.call()
似乎更好。
哪种解决方案最好?这个问题有更优雅的解决方案吗?
答案 0 :(得分:1)
使用函数几乎总是优先于eval()
。您可以使用.bind()
简化第二种方法,因此您无需单独传递函数和实例。
class A {
constructor(funcToCall) {
this.funcToCall = funcToCall;
}
displayValue() {
console.log(this.funcToCall());
}
}
// class B is the same as yours
var b1 = new B(1);
var a1 = new A(b1.computeValue.bind(b1));
a1.displayValue();
或者,如果您仍然希望单独传递实例,则可以在构造函数中使用.bind()
:
class A {
constructor(funcToCall, instance) {
this.funcToCall = funcToCall.bind(instance);
}
displayValue() {
console.log(this.funcToCall());
}
}
答案 1 :(得分:1)
是的,eval
内容非常脏,如果b1
不在适当的范围内,甚至无法正常工作。使用call
很好,但你可以做得更好:
传递实例和方法名的组合:
class A {
constructor(instance, methodName) {
this.instance = instancen;
this.methodToCall = methodName;
}
displayValue() {
console.log(this.instance[this.methodToCall]());
}
}
var a1 = new A(new B(1), "computeValue);
传递一个执行方法调用的函数以及它自己需要的任何其他函数:
class A {
constructor(funcToCall) {
this.funcToCall = funcToCall;
}
displayValue() {
console.log(this.funcToCall());
}
}
var b1 = new B(1);
var a1 = new A(() => b1.computeValue());
// or: new A(b1.computeValue.bind(b1))
// or anything else