This is more of a general question. I have seen some answers related to it before but none gave me a clear answer.
I want to achieve an auto binding function.
example:
var someObject;
var handle = function(arg1, callback){
someObject(arg1, callback.bind(???owner of callback???))
}
var handler = new Handler();
//Calling it
handle("my arg", handler.handlerFunction);
I'm not able to control the someObject way of calling the callback as it is a third party library and it is calling my callback with a reference to itself, so I can't use this inside my prototype definitions.
I can easily achieve this by using an extra argument to the handle function sending in handler and binding to it.
Or wrapping the handler.handleFunction into an apply block, but I think it would look much better if I could just call it the way I referred to to in the codeblock.
Is it possible to find the reference to the object owning handlerFunction?
I'm using Nodejs, if that has any relevance.
Unfortunately the way you want to call it doesn't work. Here is why:
When you call handle(handler.handlerFunction) the argument you pass is a reference to a function. Any information about handler is lost there. You could do this instead:
handle("my arg", handlerFunction.bind(handler));
Or this:
handler.handlerFunction = handler.handlerFunction.bind(handler);
handle("my arg", handler.handlerFunction);
There is simply nothing like that in JavaScript for some good reason.
Instead, as you already mentioned, pass in a context variable and apply your callback to it so that it runs in the owners context. This is commonly used in many frameworks etc...
Related
I am learning JavaScript and becoming confused by the logic of the code examples. From codecademy. Why are there function set-ups in function calls?
I'm quite confused. I am moving from a simplified C-like langue.
The JavaScript example
var main = function(){
$('.article').click(function(){
$('.description').hide();
$(this).children('.description').show();
});
};
My understanding:
- main is a function name with a return type of var.
$('.article') is a element/object/or class object.
.click() is a call to a member function
But:
???:
.click(function(){
$('.description').hide();
$(this).children('.description').show();
});
This seems to be a newly on the spot created function to run When/If click() is activated or run.
The way I used to think is like this:
var *p_obj = $('.article');
var *p_obj = $('.description');
var do_click()
{
p_obj2.hide();
p_obj.children(p_obj2).show();
}
var main(){
p_obj.click(do_click);
}
Function main() looks at p_obj and calls click().
Click() evaluates to true/false and run the pointer_to function do_click().
Function do_click() looks at the p_obj2 and calls hide(), which performs an action of hiding the p_obj2.
Function do_click() also looks at p_obj and uses children to scope focus to p_obj2, then it runs show(), which preforms an action of displaying p_obj2.
I do realize my C-like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
The way this design looks seems like I must write extended functionality on-the-spot for every call to .click(), so if-then .click() is run on 3 different items, I'm creating different extended functionality for each object. But I would normally create a single function that varies it's internal execution based on the object or condition click() calls it by.
This set-up seems alright if the code a relatively simple or short, but on-the-spot functional seems like overworking for longer code and code where the functionality repeats but the objects change.
Am I thinking about JavaScript functions with-in functions correctly and is this a design goal of the langue to add long repeating extended functions with-in functions?
Here, you should understand 2 things:
passing functions as arguments
anonymous functions
The first concept is particulary important because callbacks are popular in JavaScript, so let me explain it for callbacks. Imagine we have 2 functions getStuffFromWeb and processStuff. You probably expect that they are used like this:
var result = getStuffFromWeb();
processStuff(result);
But the issue here is waiting for getStuffFromWeb may take some time (the server is busy), so instead they are usually used in a "when you finish, call this function" manner, which is:
var getStuffFromWeb = function(params,callback) {
...
callback(result);
};
getStuffFromWeb(someParams,processStuff);
Well, in fact the structure of getStuffFromWeb will be different, most likely something like this:
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
So when getStuffFromWeb is called, it starts to listen to response while the code after getStuffFromWeb(someParams,processStuff); goes on evaluating. When the response comes, it calls the callback function to process the data further using the procedure we have defined (processStuff).
The second concept is rather simple: you may of'course write smth like
var processStuff = function() {...};
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
getStuffFromWeb(someParams,processStuff);
but if you use processStuff only once, why define a named function? Instead, you can just put the very same expression inside the onSuccess param like this:
var getStuffFromWeb = function(params) {
requestObject.make_request(params)
.onSuccess(function() {...});
};
getStuffFromWeb(someParams);
This looks exactly like if we took the value of processStuff and put it directly to the onSuccess's argument (and that's called anonymous function). And also we got rid of an extra argument of getStuffFromWeb.
So basically that's it.
Simple answer is that the second argument of click() requires a callback function.
This can be a named function passed as reference as in your p_obj.click(do_click); example or it can be an anonymous function with self contained logic. Anonymous functions are very common in javascript
It's the same thing just with 2 different ways of declaring the callback.
Note that the only time you would return anything from an event handler function would be to return false which effectively prevents the default browser event (url opening from href or form submit for examples) and stops event propagating up the DOM tree
main is a function name with a return type of var.
No. main is a variable which is assigned an anonymous function. The function name would go between the keyword function and the () containing the argument list.
It has no return statement so it returns undefined.
$('.article') is a element/object/or class object.
It is a call to the function $ with one argument. The return value is a jQuery object.
.click() is a call to a member function
Pretty much. In JavaScript we call any function that is the value of a property of an object as method.
This seems to be a newly on the spot created function
function () { } is a function expression. It creates a function, exactly like the one used to assign a value to main earlier. This question is worth reading for more on the subject.
When/If click() is activated or run.
The click function is called immediately. The new function is passed as an argument.
The purpose of the click function is to bind a click event handler so that when a click event hits the element later on, it will trigger the function passed as an argument.
I do realize my c -like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
Leaving aside vagaries of syntax. The main difference here is that the click event handler function is that the event handler function is stored in an intermediary variable.
You can do that in JavaScript just as easily, and then reuse the function elsewhere in the code.
var main = function(){
function show_specific_description() {
$('.description').hide();
$(this).children('.description').show();
}
$('.article').click(show_specific_description);
show_specific_description.call($(".article").last()[0]);
};
main();
is this a design goal of the langue to add long repeating extended functions with-in functions?
No. Passing a function expression as an argument is a convenient way to be more concise when you don't want to reuse the function. It's not the only way to pass functions about.
main is currently a function.
It is possible to be overwritten (even to a different type). var is not the return type, it's a statement that main is a variable.
All values should be declared as variables, within the highest scope you intend them to be used (in JS, scope typically means functions, not blocks).
You have the right idea, suspecting that the function gets passed in, and called at a later point in time (and this is actually one of the harder parts for people to get, coming from certain other languages). You'll see this behaviour all through JS.
One key thing to keep in mind in this language (you haven't hit it yet, but you will) is that JS is lexically scoped.
function getInnerX () {
var x = 5;
function getX () {
return x;
};
return getX;
}
var x = 10;
var getX = getInnerX();
console.log(getX()); // 5
The function getX inside of getInnerX has access to the references around it, at the point where it's defined (not where it's called), and thus has live access to the inner x, even if its value changes over time.
This will be another important piece of understanding what you see going on in the language, especially in the case of callbacks.
Following this melonJS tutorial, I'm stumped by a couple ways this callback is used (Scroll down to Part 2: Loading our level, you will see complete code)
// Set a callback to run when loading is complete.
me.loader.onload = this.loaded.bind(this);
I read this tutorial on callbacks, so I understand what they're used for... But I don't understand. It says this.loaded.bind(this)
1) What is the difference between this first and second this statements
2) what does doing bind and passing in (this) do?
Thank you
.bind(this) sets the context of the function
If you only set it to this.loaded, the context is not preserved
This might make a little more sense
var cntx = this;
me.loader.onload = function() {
cntx.loaded();
}
However, in this example, no arguments are passed to the loaded function. By using the bind one-liner, you preserve context, and you don't have to worry about any arguments being dropped along the way.
Read about Function.prototype.bind here
Background: I am building a webapp that makes use of JQuery and the Facebook Javascript API. Since some users don't like Facebook, I have also built a thunking layer that emulates the necessary identity APIs for users who prefer not to use Facebook. To keep things clean and avoid code duplication, I have organized my Javascript code into a few classes.
Both Facebook and JQuery APIs make extensive use of callbacks. Since all of my functions are bound into objects, I found that I am using the following pattern frequently:
var obj_ref = this;
some_jquery_function_that_takes_a_callback(/* various args */,
function() { obj_ref.my_callback_method(); });
For readability, the obj in obj_ref is actually the name of the class.
Is there some nifty Javascript magic that is simpler or clearer, or is this as good as it gets?
Update: Some good commentary so far in the answers. I should have added that my callback methods generally needs to refer to variables or functions bound to the class. If I don't need that, then the anonymous function wrapper is unnecessary.
Update2: I've selected a best answer, but you should carefully read all of the answers. Each provides some useful insight into possible solutions.
If you need your this to be your obj_ref and you can assume an update to date JavaScript (which sadly you probably can't), you could use bind to do away with the wrappers:
Creates a new function that, when called, itself calls this function in the context of the provided this value, with a given sequence of arguments preceding any provided when the new function was called.
Then you could bind your methods to your objects and this:
some_jquery_function_that_takes_a_callback(/* various args */,
function() { obj_ref.my_callback_method(); });
would be the same as:
// In some initialization pass...
obj_ref.my_callback_method = obj_ref.my_callback_method.bind(obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
Then this would be obj_ref when my_callback_method is called.
Alternatively, you could pull in Underscore.js and use its bind or bindAll. You could always grab just bind or bindAll out of Underscore.js if you didn't want the whole thing.
Or, since you have jQuery in play already, you could use $.proxy in place of the standard bind:
Takes a function and returns a new one that will always have a particular context.
So you could do it like this:
// In some initialization pass...
obj_ref.my_callback_method = $.proxy(obj_ref.my_callback_method.bind, obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
Thanks to dsfq for reminding me about jQuery's version of bind.
Better to use binding to the your object to preserve invocation context:
var objRef = this;
// #1. In this case you will have wrong context inside myCallbackMethod
// often it's not what you want. e.g. you won't be able to call another objRef methods
someJqueryFunction(a, b, objRef.myCallbackMethod);
// #2. Proper way - using proxy (bind) function
someJqueryFunction(a, b, $.proxy(objRef.myCallbackMethod, objRef));
I have the same problem with callbacks. Here's how I've dealt with it.
Just like dfsq said, $.proxy does the job for you. You don't need any extra library like underscore.
Underscore js has it's own bind function which is like the $.proxy.
Apply and call (the javascript methods that can be called on functions) work great.
Let's say I have a object :
var Dog = {
name : "Wolfy",
bark : function(){
console.debug(this.name," barks!");
}
}
var AnotherDog = {
name : "Fang"
}
Dog.bark.call(AnotherDog); //--> Fang barks!
Dog.bark(); //--> Wolfy barks!
When you write your "classes", you could use this pattern to handle the invocation of callbacks.
In case you're not sure what proxy or bind do, they do something similar to this:
var Dog = {
name : "Wolfy",
bark : function(){
console.debug(this.name," barks!");
}
}
Dog.bark = funciton(){
var scope = Dog;
return Dog.bark.apply(scope,arguments);
}
Rewrites the bark function by wrapping it in a new functions which returns the result of the original function, but forces a specific scope to be used.
I usually only wrap the callback in a function when I have to pass in extra parameters:
var x = 42;
jQuery_something({}, function(y, z) { obj_ref.callback(x, y, z) });
And that is because you don't control the arguments passed into the callback yourself. But this is only if you need a reference to some var in the scope. And in some cases this means you will have to create a closure to capture the var, e.g. in a loop.
But if that's not the case, then I just pass in a reference to the function directly:
jQuery_something({}, obj_ref.callback);
Even this should work fine, since the callback reference is in scope in this particular example (so no need to copy it to obj_ref first:
jQuery_something({}, this.callback);
Obviously, the last example is about as simple and clean as it gets: "the callback argument for the jQuery method is this object's method named 'callback'"
Yes, this is quite correct. You can have a helper function which implements the pattern though to save some code.
I've been dipping my toes into Javascript and now looking at the following piece of code:
var router = new(journey.Router)({
...
});
router.root.bind(function (res) { res.send("Welcome") });
Question: What is the root function above bound to? What does this binding do?
I understand that 'bind()' is supposed to bind the execution of a function to a specified object as a context. I do not understand how a function/method can be bound to an other function. All of the references I have looked at are talking about binding to an object.
'root' is a getter method defined in journey.js (at line 145) as
get root() {
return this.get('/');
},
which is simply an expedient shorthand for
get('/')
And in this context, the call to bind will associate the provided callback function with the route defined as root, such that any requests that match the root path ('/') will be answered by the string 'Welcome'.
UPDATED
Upon further examination of the journey.js source, it appears the use of bind() in this context is not an example of currying at all.
Rather this particular bind() is defined as a function of the object returned by route() (which in turn is called by get()) in journey.js at line 131, and is simply used to set (or bind) the handler for a particular route.
IMPORTANT: This call to bind() IS NOT the same as Function.prototype.bind().
I'm leaving my previous answer below because I believe the information regarding currying still has value in this situation.
This use of Function.prototype.bind() is called 'currying' and is used to provide a new function which has values already provided for one or more of its expected arguments.
A simple example of currying would be if you assume:
function addSome(amount, value) {
return value + amount;
}
which could be curried to produce a new function:
var addOne=addSome.bind(1);
and is exactly the same as:
function addOne(value) {
return addSome(1,value);
}
Currying is a feature from [functional programming].
See [bind - MDN Docs] for an explanation of bind() and [currying] for a formal definition of this technique.
[functional programming]:http://en.wikipedia.org/wiki/Functional_programming
[bind - MDN Docs]:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
[currying]:http://en.wikipedia.org/wiki/Currying
Not totally familiar with the object that you're using, but it's using javascript "anonymous functions" to create an object that contains a chunk of code so it can be passed around like a variable. It can later be called by appending the () onto the end.
See: http://helephant.com/2008/08/23/javascript-anonymous-functions/
Probably the most common use of this sort of thing is for setting a callback function, that is, when you call a function on router, when that function completes, it will finish by calling whatever you bound to it in the first place.
Say I'm using a generic javascript library (such as colorbox) to pop up a dialog on the screen and prompt the user for information. Once that gets done, or if the user closes the box without entering anything, I want the box to do something custom. I don't want to have to dig around in colorbox's source code to do this, so they allow places for all sort of callback functions. Say when the users enters the information and hits a button, it'll close the colorbox, submit ajax, and refresh the underlying page.
I have a script, that based upon specific scenarios, may need to supersede functions to do some processing before eventually calling the original function. (See "'overriding' Javascript Function")
I can get this working in general - here's a basic example using the jQuery plugin Tinyscrollbar (not my intended application, just something quick and easy to illustrate):
(function ($) {
// Snip..
function initalize() {
oSelf.update();
setEvents();
return oSelf;
}
// Snip..
function setEvents() {
(function () {
var oldInit = wheel;
wheel = function (oEvent) {
console.log('Intercept');
oldInit(oEvent);
}
})();
// Original event code, irrelevant to question
}
function wheel(oEvent) {
// Actual function, related to using the mousewheel
}
})(jQuery);
When I scroll the mousewheel, the console prints 'Intercept', and the scrollbar moves as originally defined. Wonderful!
However, the function name is hardcoded, and doesn't live in the global scope, so window[] is unavailable (which I like). Is there any possible combination of black magic, 'new Function()', and/or other way to loop through a potential list of function names (which may change based on other logic) and encapsulate them in this (or similar-in-spirit) manner?
Thanks in advance!
Unfortunately, there's no way to enumerate or dynamically access members in a scope object (with the convenient exception of the global scope/window object)
So you'd need to rephrase your code a bit. Instead of having free-floating functions in your outer function, have objects with methods on them. That'd make replacing those methods much easier.
There's some additional trickiness if you modify your functions after you started assigning them as event handlers or whatever. If you happen to use some kind of bind() wrapper around those functions, the correctness of your behavior will depend a lot on that bind() function.
Specifically, if you want the replacement method to retroactively become the method called for any event handler or callback it was assigned to, you'll want to use a bind() wrapper that takes a context object and a string meant to be the function name rather than a context object and a function reference. (and make sure that bind() doesn't resolve that string early to shave some ms on each calls.)
If don't don't want the retroactive behavior, you still have to make sure you don't have some bind()-ed version of the original method floating around and still being used for new callbacks after your replacement happened.