1

I have a javascript class:

MyClass = function(){
    this.m_SomeData = 5;
};

and I have created some functions for that class:

MyClass.prototype.MyClassFunction_1 = function(arg){
    // Some stuff that can return false
    return true;
};
MyClass.prototype.MyClassFunction_2 = function(arg){
    // Some stuff that can return false
    return true;
};
MyClass.prototype.MyClassFunction_3 = function(arg){
    // Some stuff that can return false
    return true;
};

Later on I have created an instance of that class. (They could be combined into a single function but there are design issues that make it nicer to separate them):

var myInstance = new MyClass();

Now the tricky bit. In an 'if' statement I am doing the following (as well as other stuff).

var funcUse;
var arg = 3; // Some value created at run time)
if((funcUse = val === 0 ? MyClassFunction_1
                        : (val === 1 ? MyClassFunction_2 : MyClassFunction_3)) !== "undefined" &&
    myInstance.funcUse(arg)){
}

The obvious problem is in the 'if' statement MyClassFunction_? are all undefined as they should be tied to an instance of the class, eg myInstance.MyClassFunction_?.

So how can this be done nicely in an if statement?

Rewind
  • 2,554
  • 3
  • 30
  • 56

2 Answers2

2

You can do this:

var funcUse =
    val === 0 ? 'MyClassFunction_1' :
    val === 1 ? 'MyClassFunction_2' :
    'MyClassFunction_3';

if (myInstance[funcUse] && myInstance[funcUse](arg)) {
    ...
}

Dot notation (obj.property) is just syntactic sugar for obj["property"], so you can simply make funcUse a string.


Alternatively, you can also do this:

var funcUse =
    val === 0 ? myInstance.MyClassFunction_1 :
    val === 1 ? myInstance.MyClassFunction_2 :
    myInstance.MyClassFunction_3;

if (funcUse && funcUse.call(myInstance, arg)) {
    ...
}

This extracts the function from the myInstance object, but then you have to be careful with calling funcUse to make sure myInstance is passed as this.

melpomene
  • 84,125
  • 8
  • 85
  • 148
1

Don't worry about "classes"/inheritance, the problem you want to solve is really two more simple ones,

  1. Accessing a property of an Object dynamically
  2. Choosing the context/this of a function

You have a couple choices about which pattern to use


fn.call / fn.apply

var o = {foo: 'bar'};

function fizz() {return this;}

fizz.call(o); // returns `o`, Object {foo: 'bar'}

Bracket notation

var o = {foo: function () {return this}};

o['foo'](); // returns `o`

In your particular case I'd probably go with a switch..case or if..else pattern to decide on the property name, then invoke with bracket notation;

var method;
switch (val) {
    case 0: method = 'foo'; break;
    case 1: method = 'bar'; break;
}

if (method)
    o[method]();
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Thanks for the informative input. I marked melpomene's answer with the tick as it appeared first. But thanks again. – Rewind Jun 18 '16 at 22:26