Different syntax for passing methods as arguments? - javascript

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.

Related

Difference between req.param = function(){} and req.param = function param() {} [duplicate]

We have two different way for doing function expression in JavaScript:
Named function expression (NFE):
var boo = function boo () {
alert(1);
};
Anonymous function expression:
var boo = function () {
alert(1);
};
And both of them can be called with boo();. I really can't see why/when I should use anonymous functions and when I should use Named Function Expressions. What difference is there between them?
In the case of the anonymous function expression, the function is anonymous — literally, it has no name. The variable you're assigning it to has a name, but the function does not. (Update: That was true through ES5. As of ES2015 [aka ES6], often a function created with an anonymous expression gets a true name [but not an automatic identifier], read on...)
Names are useful. Names can be seen in stack traces, call stacks, lists of breakpoints, etc. Names are a Good Thing™.
(You used to have to beware of named function expressions in older versions of IE [IE8 and below], because they mistakenly created two completely separate function objects at two completely different times [more in my blog article Double take]. If you need to support IE8 [!!], it's probably best to stick with anonymous function expressions or function declarations, but avoid named function expressions.)
One key thing about a named function expression is that it creates an in-scope identifier with that name for the function within the functon body:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
As of ES2015, though, a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context. In ES2015, your anonymous function expression results in a function with the name boo. However, even with ES2015+ semantics, the automatic identifier is not created:
var obj = {
x: function() {
console.log(typeof x); // "undefined"
console.log(obj.x.name); // "x"
},
y: function y() {
console.log(typeof y); // "function"
console.log(obj.y.name); // "y"
}
};
obj.x();
obj.y();
The assignment fo the function's name is done with the SetFunctionName abstract operation used in various operations in the spec.
The short version is basically any time an anonymous function expression appears on the right-hand side of something like an assignment or initialization, like:
var boo = function() { /*...*/ };
(or it could be let or const rather than var), or
var obj = {
boo: function() { /*...*/ }
};
or
doSomething({
boo: function() { /*...*/ }
});
(those last two are really the same thing), the resulting function will have a name (boo, in the examples).
There's an important, and intentional, exception: Assigning to a property on an existing object:
obj.boo = function() { /*...*/ }; // <== Does not get a name
This was because of information leak concerns raised when the new feature was going through the process of being added; details in my answer to another question here.
Naming functions is useful if they need to reference themselves (e.g. for recursive calls). Indeed, if you are passing a literal function expression as an argument directly to another function, that function expression cannot directly reference itself in ES5 strict mode unless it is named.
For example, consider this code:
setTimeout(function sayMoo() {
alert('MOO');
setTimeout(sayMoo, 1000);
}, 1000);
It would be impossible to write this code quite this cleanly if the function expression passed to setTimeout were anonymous; we would need to assign it to a variable instead prior to the setTimeout call. This way, with a named function expression, is slightly shorter and neater.
It was historically possible to write code like this even using an anonymous function expression, by exploiting arguments.callee...
setTimeout(function () {
alert('MOO');
setTimeout(arguments.callee, 1000);
}, 1000);
... but arguments.callee is deprecated, and is outright forbidden in ES5 strict mode. Hence MDN advises:
Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.
(emphasis mine)
You should always use named function expressions, that's why:
You can use the name of that function when you need recursion.
Anonymous functions doesn't help when debugging as you can't see the name of the function that causes problems.
When you do not name a function, later on its harder to understand what it's doing. Giving it a name makes it easier to understand.
var foo = function bar() {
//some code...
};
foo();
bar(); // Error!
Here, for example, because the name bar is used within a function expression, it doesn't get declared in the outer scope. With named function expressions, the name of the function expression is enclosed within its own scope.
If a function is specified as a Function Expression, it can be given a name.
It will only be available inside the function (except IE8-).
var f = function sayHi(name) {
alert( sayHi ); // Inside the function you can see the function code
};
alert( sayHi ); // (Error: undefined variable 'sayHi')
This name is intended for a reliable recursive function call, even if it is written to another variable.
In addition, the NFE (Named Function Expression) name CAN be overwritten with the Object.defineProperty(...) method as follows:
var test = function sayHi(name) {
Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
alert( test.name ); // foo
};
test();
Note: that with the Function Declaration this can not be done. This "special" internal function name is specified only in the Function Expression syntax.
Using named function expressions is better, when you want to be able to reference the function in question without having to rely on deprecated features such as arguments.callee.

named function assign to a variable [duplicate]

We have two different way for doing function expression in JavaScript:
Named function expression (NFE):
var boo = function boo () {
alert(1);
};
Anonymous function expression:
var boo = function () {
alert(1);
};
And both of them can be called with boo();. I really can't see why/when I should use anonymous functions and when I should use Named Function Expressions. What difference is there between them?
In the case of the anonymous function expression, the function is anonymous — literally, it has no name. The variable you're assigning it to has a name, but the function does not. (Update: That was true through ES5. As of ES2015 [aka ES6], often a function created with an anonymous expression gets a true name [but not an automatic identifier], read on...)
Names are useful. Names can be seen in stack traces, call stacks, lists of breakpoints, etc. Names are a Good Thing™.
(You used to have to beware of named function expressions in older versions of IE [IE8 and below], because they mistakenly created two completely separate function objects at two completely different times [more in my blog article Double take]. If you need to support IE8 [!!], it's probably best to stick with anonymous function expressions or function declarations, but avoid named function expressions.)
One key thing about a named function expression is that it creates an in-scope identifier with that name for the function within the functon body:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
As of ES2015, though, a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context. In ES2015, your anonymous function expression results in a function with the name boo. However, even with ES2015+ semantics, the automatic identifier is not created:
var obj = {
x: function() {
console.log(typeof x); // "undefined"
console.log(obj.x.name); // "x"
},
y: function y() {
console.log(typeof y); // "function"
console.log(obj.y.name); // "y"
}
};
obj.x();
obj.y();
The assignment fo the function's name is done with the SetFunctionName abstract operation used in various operations in the spec.
The short version is basically any time an anonymous function expression appears on the right-hand side of something like an assignment or initialization, like:
var boo = function() { /*...*/ };
(or it could be let or const rather than var), or
var obj = {
boo: function() { /*...*/ }
};
or
doSomething({
boo: function() { /*...*/ }
});
(those last two are really the same thing), the resulting function will have a name (boo, in the examples).
There's an important, and intentional, exception: Assigning to a property on an existing object:
obj.boo = function() { /*...*/ }; // <== Does not get a name
This was because of information leak concerns raised when the new feature was going through the process of being added; details in my answer to another question here.
Naming functions is useful if they need to reference themselves (e.g. for recursive calls). Indeed, if you are passing a literal function expression as an argument directly to another function, that function expression cannot directly reference itself in ES5 strict mode unless it is named.
For example, consider this code:
setTimeout(function sayMoo() {
alert('MOO');
setTimeout(sayMoo, 1000);
}, 1000);
It would be impossible to write this code quite this cleanly if the function expression passed to setTimeout were anonymous; we would need to assign it to a variable instead prior to the setTimeout call. This way, with a named function expression, is slightly shorter and neater.
It was historically possible to write code like this even using an anonymous function expression, by exploiting arguments.callee...
setTimeout(function () {
alert('MOO');
setTimeout(arguments.callee, 1000);
}, 1000);
... but arguments.callee is deprecated, and is outright forbidden in ES5 strict mode. Hence MDN advises:
Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.
(emphasis mine)
You should always use named function expressions, that's why:
You can use the name of that function when you need recursion.
Anonymous functions doesn't help when debugging as you can't see the name of the function that causes problems.
When you do not name a function, later on its harder to understand what it's doing. Giving it a name makes it easier to understand.
var foo = function bar() {
//some code...
};
foo();
bar(); // Error!
Here, for example, because the name bar is used within a function expression, it doesn't get declared in the outer scope. With named function expressions, the name of the function expression is enclosed within its own scope.
If a function is specified as a Function Expression, it can be given a name.
It will only be available inside the function (except IE8-).
var f = function sayHi(name) {
alert( sayHi ); // Inside the function you can see the function code
};
alert( sayHi ); // (Error: undefined variable 'sayHi')
This name is intended for a reliable recursive function call, even if it is written to another variable.
In addition, the NFE (Named Function Expression) name CAN be overwritten with the Object.defineProperty(...) method as follows:
var test = function sayHi(name) {
Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
alert( test.name ); // foo
};
test();
Note: that with the Function Declaration this can not be done. This "special" internal function name is specified only in the Function Expression syntax.
Using named function expressions is better, when you want to be able to reference the function in question without having to rely on deprecated features such as arguments.callee.

Difference between "anonymous function" and "function literal" in JavaScript?

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\"");
}

How to deal with anonymous functions in javascript functions?

I need to store an anonymous function passed as argument of my "named" function in Javascript, and then call it later.
How can I do this? I already know how to pass an anonymous function as an argument, but I don't know how to deal with it when I'm "on the other side" of the code.
Thank you
Functions in JavaScript are first-class members which means that you can work with them just as you would any other data type in the language - you can pass them as arguments, keep them as member variables inside of other functions, return them from functions etc.
In the case you've asked about, it works just like any other named variable with the neat addition that you can invoke the function as below since it is a function:
function myFunc(anonymous){
var arg1;
anonymous(arg1);
}
myFunc(function(arg1){console.log(arg1)});
Just call it using the name of the parameter.
function callThisLater(laterFunction) {
// ...
laterFunction(args);
}
callThisLater(function (arg1) {
alert("We've been called!");
});
Here is basic example:
function Foo(func) {
this.Func = func;
this.Activate = function() {
this.Func();
};
}
var foo = new Foo(function() { alert("activated"); });
foo.Activate();
I believe that what you missed is using the () to "activate" the function - as far as I understand you reached the point of "storing" the function to variable.
can you assign your anonymous function passed as an argument to a named function to a global variable inside the named function and then can used the global variable as a reference to anonymous function.

What's the meaning of "()" in a function call?

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 ...

Categories