Max
Max

Reputation: 1066

Javascript: given list of functions, how to create an object having those functions as properties?

Given:

var f1 = function(){return "a";};
var f2 = function(){return "b";};
var f3 = function(){return "c";};
transformToObject([f1, f2, f3]);

How can I create a function:

function transformToObject(arrayOfFuncs){...};

which returns:

{
    f1: function(){return "a";},
    f2: function(){return "b";},
    f3: function(){return "c";}
}

The difficulty seems to get the name of the variable to create a property of the object.

Notice: since I define functions in the form of assignment of anonymous functions to variables, the "name" property of functions won't help because it's empty, which means:

function a(){};
//a.name === "a"
var b = function(){};
//b.name === ""

Upvotes: 1

Views: 65

Answers (4)

catvir
catvir

Reputation: 196

The thing is that the names of functions are lost in Your code, and so cannot be recovered. You need to supply them somehow.

if You know them ahead and can put in an array, then Your code would simply be:

function transformToObject(fns, names) {
  var r = {};
  for (var i = 0, n = fns.length; i < n; ++i) r[names[i]] = fns[i];
  return r;
}

if You had a function which would return a name given a function:

function transformToObject(fns, namer) {
  var r = {}
  for (var i = 0, n = fns.length; i < n; ++i) r[namer(fns[i])] = fns[i]
  return r;
}

EDIT: CUT :)

Upvotes: 0

gstroup
gstroup

Reputation: 1064

Seems like you should just create the object initially, instead of the array. But if you just want to assign arbitrary function names, you can do something like this:

function transformToObject(arrayOfFuncs){
  var len = arrayOfFuncs.length,
      functionMap = {},
      funcName;
  for (i=0; i<len; i++) {
    funcName = "f" + i;
    functionMap[funcName] = arrayOfFuncs[i];
  }
  return functionMap;
};

Upvotes: 0

Eric Hotinger
Eric Hotinger

Reputation: 9306

var f1 = function(){return "a";};
var f2 = function(){return "b";};
var f3 = function(){return "c";};

var obj = {f1: f1, f2: f2, f3: f3};

alert(obj.f1());

Demo

As per your edit, perhaps something like this:

var f1 = function(){return "a";};
var f2 = function(){return "b";};
var f3 = function(){return "c";};

function transformToObject(){
    return {f1: f1, f2: f2, f3: f3};
}

var myObjectHasFunctions = transformToObject();

alert(myObjectHasFunctions.f1());

Demo2

Or something really wild:

var f1 = function a(){return "a";};
var f2 = function b(){return "b";};
var f3 = function c(){return "c";};

var arrayOfFuncs = [f1, f2, f3]

function transformToObject(arrayOfFuncs){
    var obj = {}
    obj.functions = []

    arrayOfFuncs.forEach(function(test){
        obj.functions.push({name: test.name, method: test})
    });

    return obj;
}

var myObjectHasFunctions = transformToObject(arrayOfFuncs);

myObjectHasFunctions.functions.forEach(function(func){
    alert(func.method());    
});

Demo3

But you're really best off doing something like (2) as mentioned in the various comments.

Upvotes: 3

benjaminbenben
benjaminbenben

Reputation: 1228

It is kind of possible by looking through the properties of the global scope for the matching values:

var transformToObject = (function(scope){
  return function(arrayOfFuncs){
    var obj = {};
    for(var prop in scope){
      if(scope.hasOwnProperty(prop) && arrayOfFuncs.indexOf(scope[prop]) > -1){
        obj[prop] = scope[prop]
      }
    }
    return obj
  }
})(this)

… though this is a really bad thing to do

If possible - you'd be better modifying your function to be something like:

transformToObject(['fn1','fn2','fn3']);

Better still, have the functions as properties of an object from the start.

Upvotes: 0

Related Questions