2017-02-04 11 views
0

"Aのインスタンスa1を指定できるクラスがありたい場合は、値が必要なときにBの特定のインスタンスb1の関数computeValue()を呼び出します。 "。このインスタンスでどのインスタンスのどのメソッドを使用するかを指定する必要があります。 eval()ソリューションは非常に汚れているようだと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()ソリューション:

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()ソリューション

は、これまでのところ私は2つの解決策を見つけましたより良い。

どのソリューションが最適ですか?この問題にはよりエレガントな解決策がありますか?

+0

一般的なルールとして、いつでもあなたはevalの 'の間の選択を持っている()'と何か他のもの、別のものを選んでください。 'eval()'はほとんどの場合、最後の手段であるべきです。 – Barmar

+0

'.call()'を単純化するために '.bind()'を使うことができます。 – Barmar

答えて

1

ほとんどの場合、関数の使用は、eval()より優先する必要があります。 .bind()を使用して2番目のメソッドを単純化することができるので、関数とインスタンスを別々に渡す必要はありません。

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()を使用することができます。eval事は非常に汚れているとしても動作しないことに、

class A { 
    constructor(funcToCall, instance) { 
     this.funcToCall = funcToCall.bind(instance); 
    } 

    displayValue() { 
     console.log(this.funcToCall()); 
    } 
} 
+0

ありがとう、これは本当に簡潔です! – Jecimi

1

はいb1は適切な範囲にありません。 callを使用することは結構ですが、あなたはより良い行うことができます。

  • は、インスタンスとmethodNameの組み合わせを渡します

    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 
    
+0

あなたの答えをお寄せいただきありがとうございます。あなたの答えとBarmarの答えが私の問題に答えているので、 – Jecimi

関連する問題