Now, I usually call a function (that requires no arguments) with () like this:
myFunction(); //there's empty parens
Except in jQuery calls where I can get away with:
$('#foo').bind('click', myFunction); //no parens
Fine. But recently I saw this comment here on SO:
"Consider using setTimeout(monitor, 100); instead of setTimeout('monitor()', 100);. Eval is evil :)"
Yikes! Are we really eval()-ing a string here? I guess I don't really understand the significance and implications of 'calling' a function. What are the real rules about calling and referring to functions?
In JavaScript functions are first-class objects. That means you can pass functions around as parameters to a function, or treat them as variables in general.
Let's say we are talking about a function hello,
function hello() {
alert('yo');
}
When we simply write
hello
we are referring to the function which doesn't execute it's contents. But when we add the parens () after the function name,
hello()
then we are actually calling the function which will alert "yo" on the screen.
The bind method in jQuery accepts the type of event (string) and a function as its arguments. In your example, you are passing the type - "click" and the actual function as an argument.
Have you seen Inception? Consider this contrived example which might make things clearer. Since functions are first-class objects in JavaScript, we can pass and return a function from within a function. So let's create a function that returns a function when invoked, and the returned function also returns another function when invoked.
function reality() {
return function() {
return function() {
alert('in a Limbo');
}
};
}
Here reality is a function, reality() is a function, and reality()() is a function as well. However reality()()() is not a function, but simply undefined as we are not returning a function (we aren't returning anything) from the innermost function.
So for the reality function example, you could have passed any of the following to jQuery's bind.
$('#foo').bind('click', reality);
$('#foo').bind('click', reality());
$('#foo').bind('click', reality()());
Your jQuery bind example is similar to setTimeout(monitor, 100);, you are passing a reference of a function object as an argument.
Passing a string to the setTimeout/setInterval methods should be avoided for the same reasons you should avoid eval and the Function constructor when it is unnecessary.
The code passed as a string will be evaluated and run in the global execution context, which can give you "scope issues", consider the following example:
// a global function
var f = function () {
alert('global');
};
(function () {
// a local function
var f = function() {
alert('local');
};
setTimeout('f()', 100); // will alert "global"
setTimeout(f, 100); // will alert "local"
})();
The first setTimeout call in the above example, will execute the global f function, because the evaluated code has no access to the local lexical scope of the anonymous function.
If you pass the reference of a function object to the setTimeout method -like in the second setTimeout call- the exact same function you refer in the current scope will be executed.
You are not doing the same thing in your jQuery example as in the second setTimeout example - in your code you are passing the function and binding the click event.
In the first setTimout example, the monitor function is passed in and can be invoked directly, in the second, the sting monitor() is passed in and needs to be evaled.
When passing a function around, you use the function name. When invoking it, you need to use the ().
Eval will invoke what is passed in, so a () is required for a successful function invocation.
First of all, "()" is not part of the function name.
It is syntax used to make function calls.
First, you bind a function to an identifier name by either using a function declaration:
function x() {
return "blah";
}
... or by using a function expression:
var x = function() {
return "blah";
};
Now, whenever you want to run this function, you use the parens:
x();
The setTimeout function accepts both and identifier to a function, or a string as the first argument...
setTimeout(x, 1000);
setTimeout("x()", 1000);
If you supply an identifier, then it will get called as a function.
If you supply an string, than it will be evaluated (executed).
The first method (supplying an identifier) is preferred ...
Related
I have seen, mostly in event handlers, functions called Pascal-style, i.e. without the brackets. Is there a difference between myFunction and myFunction(), and if so, what is it?
You always use parentheses when you want to call a function.
The reason that you use it without parentheses when you want it to be a callback function is that you don't want to call the function when you assign it to the event. The event will call the function when the event is triggered.
You can pass a function reference around like any other value, and use parentheses when you want to call it. Example:
function test() {
alert('test');
}
var x = test; // got the reference
var y = x; // copying it around
y(); // calling the function
myFunction is function object and can be passed around like any other object / variable, usually as callback.
myFunction() invokes a function without any parameters and value of this expression is what myFunction function returns.
Pascal-style functions are not functions without brackets. Pascal-style functions represent function names that do not have first letter capitalized.
By some conventions only constructor functions should have first letter capitalized, because invoking a constructor function as a regular function (without new) and regular function as constructor can provoke serious bugs that are hard to find.
I'm currently trying to teach myself more about javascript, and I find myself stumbling over the syntax for passing a method as an argument to another method call. Say you have two functions like these:
function FirstFunction()
{
DoesSomething();
}
function SecondFunction(func)
{
func();
}
In actually passing the FirstFunction to the SecondFunction, I seem to see a wild variety of variations on doing so:
SecondFunction(FirstFunction);
or
SecondFunction("FirstFunction()");
or sometimes, if FirstFunction was defined as follows:
var thisisafunction = function FirstFunction()
{
DoesSomething();
}
SecondFunction(thisisafunction);
I'm guessing there's no "one right way" to do this, so when is it appropriate to use each way of passing a function? Is it better to use one way over another in a certain situation?
Passing a string is always bad. It only works with functions like setTimeout which automatically eval() strings and it's bad since it runs in the global context.
If you just want to pass a plain function without creating a closure or passing arguments, passing the function without () is fine:
myFunc(someCallbackFunc);
If you need to pass arguments or want a closure so you can access some non-global variables inside that function, use an anonymous function:
myFunc(function() {
someCallbackFunc('meow');
});
Of course you can also assign the function to a variable first:
var cb = function() {
someCallbackFunc('meow');
};
myFunc(cb);
While var cb = function someName() {}; is valid, I'd recommend against giving your function expressions names - it's not supported by all browsers. The only advantage is having a function name in debuggers anyway...
First let me clear something. You can define functions both as:
function name() { ... };
or assign it to a variable
var myFunc = function() { ... };
you don't mix both by doing
var myFunc = function name() { ... }; //WRONG
since name won't be binded to anything.
After this, the most usual way of passing functions as arguments, is just to pass the function object without the function call operator "()", which means the function object is not executed.
var func1 = function() { console.log("func1 here") };
var func2 = function(f) { f(); };
func2(func1);
Also, passing the function as String with the function call operator means that the receiving function will have to evaluate that using eval() for the function argument to be executed. It is not recommended.
Based on some code in a lecture by Doug Crockford, I've created this.
var isAlphaUser = (function() {
alert("Forming Alpha User List");
let AlphaUsers = {
1234: true,
5678: true
};
return function(id){
alert("Checking Alpha Users:",id);
return AlphaUsers[id];};
}());
alert("starting");
alert(isAlphaUser(1234));
alert(isAlphaUser(5678));
alert(isAlphaUser(3456));
which gives me this:
Forming Alpha User List
starting
Checking Alpha Users: 1234
true
Checking Alpha Users: 5678
true
Checking Alpha Users: 3456
undefined
Which is quite cool, as it does the expensive setup once only, and every further call is a cheap check.
However, I can't decipher the code that does this. Specifically, I can't understand why I need the "()" at the end of the function declaration.
Can somebody explain how this syntax is working?
() calls a function. function() { } defines a function. Appending () right after immediately calls it1, and the result (also an anonymous function) is assigned to isAlphaUser.
The function() { ... }() pattern is frequently used to isolate variables to an inner scope, so those variables don't become part of the global scope.
In this case, this is what happens:
An anonymous function is run, defining a variable AlphaUsers inside that scope.
That function returns another function that takes 1 parameter. This function is a closure to which the AlphaUsers variable becomes bound (in other words, available). This function checks if the parameter passed in is contained in AlphaUsers (actually, it returns the item at that index, which is just a boolean).
The return value is assigned to a variable isAlphaUser.
Since isAlphaUser is now a function, it can be called to see if the parameter is contained in the AlphaUsers variable, but no direct access to AlphaUsers is available in the global scope (it become a sort of private variable).
1 — Note: As cwolves mentioned in the comments, beware that while () appended directly after the } works in this case, it is only because in this case the function definition is a function expression. If function is the first word on the line, the line becomes a function declaration, and that is all that line can do, the function is not anonymous (it will require a name, otherwise it's a syntax error) and cannot be called immediately inline. See Function Declarations vs. Function Expressions for more info.
The () at the end of the code is separate from the closure issue. By wrapping your function in parens and adding the () at the end you are creating an anonymous function that is run immediately with whatever arguments you pass into ().
Specifically, I can't understand why I need the "()" at the end of the
function declaration.
It creates self-invoking function, in other words, the function is executed as soon as it is parsed.
It is basically same thing when you call a function by suffixing it with () like:
myfunc(); // call this func
The top-level anonymous function returns the function that the isAlphasUser varaible refers to.
You need to call the top-level function, to get the inner-function reference.
Think of it like this, the outer anonymous function is a function factory, i.e., it returns a function.
In order to use any function (even one that returns a function) you must call it.
Let's say I have a function:
function myFunction() {
...
}
I want to call it from event handler. Why this construction doesn't call my function?
$(window).resize(myFunction());
But this does the trick:
$(window).resize(function(){myFunction()});
What is the difference between these types of calling?
$(window).resize(myFunction());
immediately calls myFunction and passes the return value to resize. Adding parenthesis after a function name/reference calls the function.
On the other hand,
$(window).resize(function(){myFunction()});
passes an anonymous function to resize. myFunction is only called when the outer function is called.
Anonymous functions are nothing special. In this case it is just some kind of inline function definition. You can easily replace it with a function reference:
var handler = function(){myFunction()}; // take out the function definition
$(window).resize(handler); // and replace it with the new name
Now you can see that there are no parenthesis after the function name, which means, handler is not called, only the reference is passed.
I hope you can also see now that creating a new function in this example is not necessary. You can achieve the same by simply passing a reference to myFunction:
$(window).resize(myFunction);
But both ways have their use cases.
The first example $(window).resize(myFunction()); can still be useful if myFunction returns a function that should be used as event handler:
function myFunction() {
var handler = function() {};
return handler;
}
Maybe the handler retuned depends on a parameter passed to myFunction.
Passing an anonymous function is necessary if you want to call myFunction with some specific arguments:
function myFunction(a, b) {
alert(a + b);
}
$(window).resize(function(){
myFunction(40, 2);
});
Update:
#T.J. Crowder made an important comment about the event object. Every event handler gets the event object passed as first parameter. If you'd define your function as
function myFunction(event) {
...
}
to have (easier) access to it, using an anonymous function, you would have to pass it through:
$(window).resize(function(event){myFunction(event)});
if you want to use it.
The book Learning JavaScript defines anonymous functions as follows...
Functions are objects. As such, you can create them - just like a String or Array or other type - by using a constructor and assigning the function to a variable. In the following code, a new function is created using the Function constructor, with the function body and argument passed in as arguments:
var sayHi = new Function("toWhom", "alert('Hi' + toWhom);");
This type of function is often referred to as an anonymous function because the function itself isn't directly declared or named.
Is this the correct definition of an "anonymous function" in JavaScript? If not, what is an anonymous function, and is there any difference between an anonymous function and a function literal?
Function expressions and function declarations
Since you are interested in functions, here is some important stuff to know.
var abc = function() { ... } is known as a function expression. The variable will be assigned that anonymous function at execution time, though its variable declaration will be hoisted to the top of the current execution context (scope).
However, a function expression can be given a name too, so that it can be called within its body to make it recursive. Keep in mind IE has some issues with this. When you assign it a name, it is most definitely not an anonymous function.
A function such as function abc() { ... } is known as a function declaration. Its definition is hoisted to the top of its scope. Its name is available within it and its parent's scope.
Further Reading.
Your Example
It is an anonymous function, but assigned to the variable sayHi.
As Šime Vidas mentions, a new Function object is instantiated with the new operator, and the arguments and function body are passed in as strings. The resulting object is assigned to sayHi.
The real world use of creating a function using this method is rare (though it may be just to help show that functions are objects). I also believe passing its arguments list and function body as a string will invoke an eval() type function, which is rarely good when a much better construct is available.
Also, functions created with Function do not form a closure.
I would only use this method if for some reason I needed to create a Function with its arguments and/or body only available to me as a string.
In the real world, you'd do...
var sayHi = function(toWhom) {
alert('Hi' + toWhom);
};
Also refer to comments by Felix and Šime for good discussion and further clarification.
I think a broader and more accepted definition of an anonymous function is a function that is created without a name.
An anonymous function is simply a function with no name.
function(a, b){
return a + b;
}
The above code would be useless as it has no name to which you could call it with. So they are usually assigned to a variable.
var func = function(a, b){
return a + b;
}
This is helpful because you can pass an anonymous function to another function or method without having to create the function before hand, as demonstrated below.
function bob(a){
alert(a());
}
bob(function(){
return 10*10;
})
This:
new Function("toWhom", "alert('Hi' + toWhom);")
and this:
function(toWhom) { alert('Hi' + toWhom); }
are two expressions that produce the same result - they return a new anonymous function object.
The second expression (and only the second expression) is called a function expression. You may also call it a function literal (although we could argue that a function declaration is also a function literal).
function foo(){
alert("i'm foo, nice to meet you!");
}
var bar = function(){
alert("I am an anonymous function assigned to the variable \"bar\"");
}