Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将特定实例的特定方法作为参数传递_Javascript_Es6 Class - Fatal编程技术网

Javascript 将特定实例的特定方法作为参数传递

Javascript 将特定实例的特定方法作为参数传递,javascript,es6-class,Javascript,Es6 Class,我希望有一个类,我可以在其中指定“a的实例a1,当需要值时,您将调用B的特定实例b1的函数computeValue()。我需要指定此实例将使用哪个实例的哪个方法 到目前为止,我找到了两种解决方案: eval()解决方案: class A { constructor(funcToCall) { this.funcToCall = funcToCall; } displayValue() { console.log(eval(this.funcToCall));

我希望有一个类,我可以在其中指定“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
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
函数.call()
解决方案:

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
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()
解决方案似乎非常肮脏,
函数.call()
似乎更好


哪种解决方案最好?这个问题有没有更优雅的解决方案?

使用函数几乎总是优于
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());
    }
}

使用函数几乎总是优于
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());
    }
}

是的,
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
    

    • 是的,
      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
        

      一般来说,当您在
      eval()
      和其他内容之间进行选择时,请选择其他内容
      eval()
      几乎应该是最后的选择。您可以使用
      .bind()
      来简化
      .call()
      解决方案。一般来说,在
      eval()
      和其他解决方案之间进行选择时,请选择其他解决方案
      eval()
      应该是最后的选择。您可以使用
      .bind()
      来简化
      .call()
      解决方案。谢谢,这确实更简洁了!谢谢,这确实更简洁了!谢谢你的回答,你的回答和巴玛的回答都回答了我的问题,所以我勾选了一个。谢谢你的回答,你的回答和巴玛的回答都回答了我的问题,所以我勾选了一个