Reputation: 86413
I'm not exactly sure how to ask this question, so I'll do it by example. Say I have this set up:
var x = function() {
console.log('YAY!');
};
x.test0 = 0;
x.test1 = 1;
x.test2 = "hello world";
that works as expected:
x(); // YAY!
x.test0 // 0
x.test2 // "hello world"
Now, I would like to know how to set this up starting with an object first. I tried adding the function using constructor, but that doesn't work.
var x = {
test0 : 0,
test1 : 1,
test2 : 'hello world',
constructor: function() {
console.log('YAY!');
}
}
x(); // object is not a function
x.test0 // 0
x.test2 // "hello world";
I've tried other crazy things, but nothing seems to work.
Any ideas? Or am I stuck doing it the first way?
Upvotes: 0
Views: 143
Reputation: 2985
To put it simply you can't. Why? because the types of both the objects are different first a Function Object
and second returns a standard object. So both inherits from different ancestors. The only possibility here is if you can cast object to a function and there's no such thing available n JavaScript natively. However you can use your own cast method.
function toFunction (obj, fnProp) {
var fn = function () {};
if (typeof obj[fnProp] !== 'function') return fn;
else {
fn = obj[fnProp];
for (prop in obj) {
fn[prop] = obj[prop];
}
}
return fn;
}
var z = toFunction(y, 'prototype'); // with your example
Upvotes: 1
Reputation: 115940
As demonstrated by your first example, functions in JavaScript are objects and can have properties.
ECMAScript defines "internal properties" (and internal methods) for objects. These internal properties help define the state of an object, but not all of an object's internal properties are directly settable from code. We denote an internal property name with double square brackets, like [[Foo]]
.
When you call a function like foo()
, you run the object's [[Call]]
internal method. However, only function objects have a [[Call]]
internal method. It is not possible to set or change a non-host object's [[Call]]
method; it is set when the object is defined and there is no mechanism defined by ECMAScript to change it. ("Host" objects are objects supplied by the browser or other execution environment and can play by different rules. Unless you're writing a browser, you probably don't need to consider this exception.)
Thus, if you define a function
foo = function() { doStuff(); return 5; };
that function (which is assigned to the variable foo
) has a permanent [[Call]]
method (per the function-creation rules in section 13.2), which runs doStuff
and returns 5
.
If you have a non-function object
foo = { };
that object is lacking a [[Call]]
property. There is no way to give it a [[Call]]
property, because non-host objects can only set [[Call]]
at definition-time. The logical internal property [[Call]]
does not correspond to any object property accessible in actual code.
In sum, making a non-function object callable is not possible. If you want an object to be callable, define it initially as a function, as you do in your first example.
Upvotes: 3
Reputation: 1015
Did not got exactly what you want, do you want something like object oriented? This may help
function x(){
this.test0 = 0;
this.test1 = 1;
this.test2 = 'hello word';
console.log('Wow!');
}
var y = new x(); // new object of x PRINTS WOW and set's default values
console.log(y.test0) // 0
console.log(y.test2) // "hello world";
Upvotes: 0
Reputation: 28114
You can't just create an object and later run it as if it were a function.
You can do it the other way around, as in JavaScript a function is an object:
x.prop=1;
console.log(x.prop);
function x() {
return true;
}
Upvotes: 0