3

I often need to pass methods from objects into other objects. However I usually want the method to be attached to the original object (by attached I mean 'this' should refer to the original object). I know a few ways to do this:

a) In the object constructor: ObjectA = function() { var that = this; var method = function(a,b,c) { that.abc = a+b+c }}

b) In objectA which has been passed objectB: objectB.assign(function(a,b,c) { that.method(a,b,c) })

c) Outside both objects: objectB.assign(function(a,b,c) { objectA.method(a,b,c) })

I want to know if there is a simpler way to pass methods attached to their original objects.

3 Answers 3

4

You can define a "createDelegate" method for all functions:

Function.prototype.createDelegate = function(scope) {
    var method = this;
    return function() {
        return method.apply(scope, arguments);
    }
}

And then use like:

var myDelegate = myFunction.createDelegate(myScope);

calling "myDelegate" will execute "myFunction" with "this" pointing to "myScope" and the same arguments as passed to myDelegate

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, this is perfect! Although I don't understand it yet.
It may also be worth looking at the current (1.7 RC 2) source of Prototype's Function#bind, which serves the same purpose as ob1's createDelegate but which went through quite a round of performance testing and optimization a few months back: github.com/sstephenson/prototype/blob/master/src/lang/… Separately: I'd use scope || undefined rather than scope || window, to avoid the unnecessary browser-specificity and issues with window being overwritten. Calls to apply using undefined as the scope will use the global object.
@peterjwest: "Although I don't understand it yet." It's basically doing what you were doing: Creating a function that, when called, will call the actual target function using the given context (this value). Sometimes it's more efficient to use a closure for this (where you have var self = this and then a function that uses self.foo() that closes over it), other times it's more efficient to create a delegate as with ob1's example -- and the latter is clearer to people who are relatively new to Javascript and/or who don't understand closures very well, which is of value.
What kind of efficiency are you talking about: programming or performance? Could you give some examples of when either method is preferable?
@T.J. The provided implementation does this exact thing - creates a function which closes over the method, scope and callArgs.
|
0

As long as you call the other method with its appropriate owner object, this will always refer to the correct owner.

1 Comment

How do you propose I would do this? Pass the object and a string representing the method: assign(object, 'method')? I don't want the method name to be hard coded in the other object
0

You can delegate if you like, or just call the object that lacks the method from the defined method scope-

instance.method.call(Other-Object/*,argument,...*/)

For example, if Array has a filter method, you can call it as if it were a method of a node list object.

var list=document.getElementsByTagName('p'), a=[], 

list= a.filter.call(list,function(itm){return itm.className=='sidebar'});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.