1

How can I check If a prototyped function exists?

A little more explanation:

As you can see in the sample code, I will always have a commonFunction() for both X1 and X2.

I would like to tell if X1 and X2 have their own myOwnFunction().

It's important to notice that at first hand I don't know which function I will be calling. That's why I need a dynamic way to gather that information.

CODE:

function FunctionMain (){};

FunctionMain.FunctionSub = new FunctionSub();

function FunctionX1()
{
    FunctionX1.prototype.commonFunction = function()
    {
        console.log("Hello, I'm X1");
    }

    FunctionX1.prototype.myOwnFunctionX1 = function()
    {
        console.log("This my own function");
    }    
}

function FunctionX2()
{
    FunctionX2.prototype.commonFunction = function()
    {
        console.log("Hello, I'm X2");
    }

    //I don't have myOwnFunctionX2()
}

function FunctionSub()
{
    FunctionSub.prototype.FunctionX1 = new FunctionX1();
    FunctionSub.prototype.FunctionX2 = new FunctionX2();
}

//This call works!
FunctionMain.FunctionSub.FunctionX1.commonFunction();
FunctionMain.FunctionSub.FunctionX2.commonFunction();


//what kind of test should I use?
if(typeof "FunctionMain.FunctionSub.FunctionX1.myOwnFunctionX1" == "function")
{
    console.log("It exists!");
}

if(typeof window["FunctionMain.FunctionSub.FunctionX1.myOwnFunctionX1"] == "function")
{
    console.log("It exists!");
}

FIDDLE: http://jsfiddle.net/matias/FTzjW/

Matías Cánepa
  • 5,770
  • 4
  • 57
  • 97

2 Answers2

7

This is weird, don't do this

function FunctionX2()
{
    FunctionX2.prototype.commonFunction = function()
    {
        console.log("Hello, I'm X2");
    }

    //I don't have myOwnFunctionX2()
}

Do this instead

var FunctionX2 = function() {
  // constructor
};

FunctionX2.prototype.commonFunction = function() {
  console.log("Hello, I'm X2");
};

Check if it exists directly

typeof FunctionX2.prototype.commonFunction === 'function';
// => true

Or with an instance

var f2 = new FunctionX2();
typeof f2.commonFunction === 'function';
// => true

Here's a demonstration that checking for the function dynamically is possible

var functionExists = function(receiver, functionName) {
  return typeof receiver[functionName] === 'function';
};

var commonFunctionExists = function(receiver) {
  return functionExists(receiver, 'commonFunction');
};

Some tests

var f1 = new FunctionX1();
commonFunctionExists(f1);
// => true

var f2 = new FunctionX2();
commonFunctionExists(f2);
// => true

var obj = new Object();
commonFunctionExists(obj);
// => false
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • Remember what I said: "It's important to notice that at first hand I don't know which function I will be calling. That's why I need a dynamic way to gather that information". You are explictly checking for FunctionX2 – Matías Cánepa Jul 19 '13 at 21:08
  • 1
    It's clear to me that you're structuring your program wrong. I mean, just by the look of the way you're coding the classes in JavaScript alone. It seems as though you have a misunderstanding of the fundamentals somewhere. I'm willing to help you, but how about instead of fixing the code above, let's look at what your goal is first. Here's an example: Instead of asking, "how do I weigh an elephant with a bathroom scale?" ask "How can I be sure my pet elephant is not overweight?" – Mulan Jul 19 '13 at 22:48
  • The difference being: ask how you should accomplish your goal, not how to implement a solution you think will accomplish your goal. The former opens the doors for many possible solutions whereas the latter pigeonholes you into a single solution that might be flawed from the start. – Mulan Jul 19 '13 at 22:52
  • For what it's worth, I added a demonstration at the end of my answer – Mulan Jul 19 '13 at 22:59
-3

This is the solution that worked for me.

Check this jsbin (don't know why this doesn't work in jsfiddle)

FULL CODE:

function FunctionMain (){}

FunctionMain.FunctionSub = new FunctionSub();

function FunctionX1()
{
    FunctionX1.prototype.commonFunction = function()
    {
        console.log("Hello, I'm X1");
    }

    FunctionX1.prototype.myOwnFunctionX1 = function()
    {
        console.log("This my own function");
    }    
}

function FunctionX2()
{
    FunctionX2.prototype.commonFunction = function()
    {
        console.log("Hello, I'm X2");
    }

    //I don't have myOwnFunctionX2()
}

function FunctionSub()
{
    FunctionSub.prototype.FunctionX1 = new FunctionX1();
    FunctionSub.prototype.FunctionX2 = new FunctionX2();
}

//This call works!
FunctionMain.FunctionSub.FunctionX1.commonFunction();
FunctionMain.FunctionSub.FunctionX2.commonFunction();


//use this test
function testFunction(function_to_find)
{
    var context = window;
    var functions = function_to_find.split(".");
    var method = functions.pop();

    for (var i = 0; i < functions.length; i++)
    {
        context = context[functions[i]];
    }

    return typeof context[method];
}

if(testFunction("FunctionMain.FunctionSub.FunctionX1.myOwnFunctionX1") == "function") console.log("yes x1!");

if(testFunction("FunctionMain.FunctionSub.FunctionX2.myOwnFunctionX2") == "function") console.log("yes x2!");
Matías Cánepa
  • 5,770
  • 4
  • 57
  • 97
  • What happens when context becomes undefined before reaching the end? EDIT: I see that's exactly what happened in your fiddle. – Adam Jenkins Jul 20 '13 at 00:35
  • @Adam I'm sorry, I didn't understand you. Can you explain me? – Matías Cánepa Jul 20 '13 at 00:59
  • Still setting the prototype within the constructor body, that is wrong. Do you have any idea what the prototype is for? http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 to check what properties an object has you can use `for(something in myObject)` `hasOwnProperty` and go up the constructor `myObject=myObject.constructor` untill you reach Function. But the way you inherit now you're destroying the constructor property on the object's prototype. – HMR Jul 20 '13 at 01:34
  • This is so far beyond how you should be attempting this stuff. I made a ton of effort to help you via the comments and demonstration in my answer. If you want to force a broken solution instead of learn something, no one will be able to help you; not even yourself. – Mulan Jul 20 '13 at 02:43