How to convert an "object" into a function in JavaScript?

Viewed 28833

JavaScript allows functions to be treated as objects--if you first define a variable as a function, you can subsequently add properties to that function. How do you do the reverse, and add a function to an "object"?

This works:

var foo = function() { return 1; };
foo.baz = "qqqq";

At this point, foo() calls the function, and foo.baz has the value "qqqq".

However, if you do the property assignment part first, how do you subsequently assign a function to the variable?

var bar = { baz: "qqqq" };

What can I do now to arrange for bar.baz to have the value "qqqq" and bar() to call the function?

8 Answers

It's easy to be confused here, but you can't (easily or clearly or as far as I know) do what you want. Hopefully this will help clear things up.

First, every object in Javascript inherits from the Object object.

//these do the same thing
var foo = new Object();
var bar = {};

Second, functions ARE objects in Javascript. Specifically, they're a Function object. The Function object inherits from the Object object. Checkout the Function constructor

var foo = new Function();
var bar = function(){};
function baz(){};

Once you declare a variable to be an "Object" you can't (easily or clearly or as far as I know) convert it to a Function object. You'd need to declare a new Object of type Function (with the function constructor, assigning a variable an anonymous function etc.), and copy over any properties of methods from your old object.

Finally, anticipating a possible question, even once something is declared as a function, you can't (as far as I know) change the functionBody/source.

There doesn't appear to be a standard way to do it, but this works.

WHY however, is the question.

function functionize( obj , func )
{ 
   out = func; 
   for( i in obj ){ out[i] = obj[i]; } ; 
   return out; 
}

x = { a: 1, b: 2 }; 
x = functionize( x , function(){ return "hello world"; } );
x()   ==> "hello world" 

There is simply no other way to acheive this, doing

x={}
x() 

WILL return a "type error". because "x" is an "object" and you can't change it. its about as sensible as trying to do

 x = 1
 x[50] = 5
 print x[50] 

it won't work. 1 is an integer. integers don't have array methods. you can't make it.

Use a temporary variable:

var xxx = function()...

then copy all the properties from the original object:

for (var p in bar) { xxx[p] = bar[p]; }

finally reassign the new function with the old properties to the original variable:

bar = xxx;

JavaScript allows functions to be treated as objects--you can add a property to a function. How do you do the reverse, and add a function to an object?

You appear to be a bit confused. Functions, in JavaScript, are objects. And variables are variable. You wouldn't expect this to work:

var three = 3;
three = 4;
assert(three === 3);

...so why would you expect that assigning a function to your variable would somehow preserve its previous value? Perhaps some annotations will clarify things for you:

// assigns an anonymous function to the variable "foo"
var foo = function() { return 1; }; 
// assigns a string to the property "baz" on the object 
// referenced by "foo" (which, in this case, happens to be a function)
foo.baz = "qqqq";
Related