Reputation: 391
After looking around a bit, I couldn't find an answer to this question, though I suspect it's been asked before. The closest I could find is this Function pointers in objects though it doesn't get quite what I'm after.
Suppose we have a piece of code like this:
var foo = function () { /* some code */ };
now, I'm assuming that during evaluation time the name foo is bound in it's environment to an internal representation of the function, that is then looked up during application time.
Now suppose we have , a little later in the program, an object:
var obj = {};
obj.func = foo;
At this point, there should be two copies of the same function object in the environment, one bound to foo, the other bound to obj.func. But let's say I don't want two copies of that function, but rather have obj.func point back towards foo--is there a way to do this? This is what I've come up with:
var obj = {};
obj.func = function () { foo(); };
Would this work? Is there a better way?
Many thanks
EDIT FOR CLARIFICATION
Apologies--I don't think I was being clear enough. I hope this helps.
I'm not sure how the Javascript evaluation process works, but let's say it keeps track of some internally represented environment, which we'll represent abstractly here as a set of key value pairs.
Now, when the evaluator sees some code such as
var foo = function () { /* some code */ };
it constructs this in it's environment: ['foo' : [function object]]. And then, later on, when it sees something like this:
var bar = foo;
it looks up foo in the environment to retrieve it's value, a function object, and then augments the environment like so. ['foo' : [function object], 'bar' : [function object]]. Now the same function really is there twice in the environment. Is this how javascript sets up its environment? If not, then how does it do so?
My motivation for asking is as follows. Let's say we define some functions, and then later an object that we export that functions as an interface to those functions, and which we know we're going to instantiate many times. It would be more efficient if the object contained pointers to functions, rather than the functions themselves.
Upvotes: 4
Views: 5336
Reputation: 86525
JS variables, object properties, etc do not hold objects directly; they hold references to objects. When you say var foo = function() { };
, foo
is assigned a reference to that function you just defined. (Not a pointer, by the way. The difference can be subtle, but important. JS has no user-visible pointers, so it's not as much of an issue. But the languages that do, use them differently. Don't make yourself have to unlearn stuff later.)
And later in the program, when you say obj.func = foo;
, you're copying the reference into obj.func
. Not the function -- there's still only one function object, with two references to it.
So obj.func = foo;
already does what you were saying. When you call obj.func()
, it's actually calling the exact same function that's referenced by foo
. There's one huge difference, though, and this may be what's causing you trouble: obj.func
is a "method call", and JS sets this
to obj
inside the function. If foo
was using this
for anything, assuming it was some other object, it's going to be disappointed.
If that's a problem, you might do something like
var that = this;
var foo = function() { /* use `that` instead of `this` here */ };
Then, whether you call the function as foo
or obj.func
, it's not affected by the changed this
.
If this doesn't help, you'll need to clarify the question.
Upvotes: 8
Reputation: 1003
Just to elaborate a bit:
functions are first class citizens or objects in javascript. They are used just like any other objects.
var foo = func() {
//some code
};
is the analogous to
var foo = {
//some code
};
In Javascript, all objects are passed by reference. As far as I know there is no concept of a pointer or pass by value for javascript objects.
So when you assign two references to the same function, the function object is not copied. However, the internal state of the function remains the same for both the references. In your case foo and obj.func()
Upvotes: 0
Reputation: 26753
This isn't true:
At this point, there should be two copies of the same function object in the environment, one bound to foo, the other bound to obj.func. But let's say I don't want two copies of that function, but rather have obj.func point back towards foo
If you assign things that way then obj.func and foo point to the same thing. I don't even think it's possible to copy a function.
Upvotes: 0
Reputation: 44396
At this point, there should be two copies of the same function object in the environment, one bound to foo, the other bound to obj.func.
You think so? Just out of curiosity, if the code said:
var obj = {};
obj.func = 5;
How many copies of 5
are floating around?
No. All code is translated to functions, which are essentially constants. You can assign several variables to the same constant without any trouble.
As for "binding", binding occurs when the function is called. That is, the this
parameter is set to obj
and whooosh...
Upvotes: -1
Reputation: 30102
Have you tried running your example?
Yes, that does work, however be aware that if you change the foo
variable it will also change the functionality of objc.func()
.
I don't know any other way to do this.
Upvotes: 0