Why do you need to invoke an anonymous function on the same line?
Drop the semicolon after the function definition.
(function (msg){alert(msg)})
('SO');
Above should work.
DEMO Page: https://jsfiddle.net/e7ooeq6m/
I have discussed this kind of pattern in this post:
jQuery and $ questions
EDIT:
If you look at ECMA script specification, there are 3 ways you can define a function. (Page 98, Section 13 Function Definition)
1. Using Function constructor
var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30
2. Using Function declaration.
function sum(a, b)
{
return a + b;
}
alert(sum(10, 10)); //Alerts 20;
3. Function Expression
var sum = function(a, b) { return a + b; }
alert(sum(5, 5)); // alerts 10
So you may ask, what's the difference between declaration and expression?
From ECMA Script specification:
FunctionDeclaration :
function Identifier ( FormalParameterListopt ){ FunctionBody
}FunctionExpression :
function Identifieropt ( FormalParameterListopt ){ FunctionBody
}
If you notice, 'identifier' is optional for function expression. And when you don't give an identifier, you create an anonymous function. It doesn't mean that you can't specify an identifier.
This means following is valid.
var sum = function mySum(a, b) { return a + b; }
Important point to note is that you can use 'mySum' only inside the mySum function body, not outside. See following example:
var test1 = function test2() { alert(typeof test2); }
alert(typeof(test2)); //alerts 'undefined', surprise!
test1(); //alerts 'function' because test2 is a function.
Live Demo
Compare this to
function test1() { alert(typeof test1) };
alert(typeof test1); //alerts 'function'
test1(); //alerts 'function'
Armed with this knowledge, let's try to analyze your code.
When you have code like,
function(msg) { alert(msg); }
You created a function expression. And you can execute this function expression by wrapping it inside parenthesis.
(function(msg) { alert(msg); })('SO'); //alerts SO.
Why is it useful to have an anonymous function stored as a variable, and pass it to higher order functions?
The brackets are only there when you're calling the function. If you pass the call with the brackets into the .filter() method, you'll actually be passing the result of the call, rather than a pointer to the call itself. The alternative is to pass in the entire function into the filter function, but readability tends to suffer. It also limits your ability to modify what's going into the function you're putting it in.
Imagine a case where you might want to do a sort instead of a filter, and you wanted to change the sort based on a boolean passed in.
Take this basic sort for example:
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
return a - b;
});
What if you wanted to be able to choose which direction it was sorted based on another variable. You can define both sort functions, and then pass the correct one for the sort you want.
var numbers = [4, 2, 5, 1, 3];
var sortAscending = function(a, b) {
return a - b;
}
var sortDescending = function(a, b) {
return b - a;
}
function doSort(myArray, dir) {
var sortMethod = (dir == "asc") ? sortAscending : sortDescending;
myArray.sort(sortMethod );
}
doSort(numbers, "asc");
The above illustrates how passing the method call this way allows for more flexibility when you need it, and ensures the call is made only when it's executed inside sort.
Why do I have to use an anonymous function instead of passing an additional argument to `setTimeout`?
The difference is the moment in time at which rAF
is evaluated.
Explanation
Presumably, your code looks something like this:
let rAF;
const draw = () => {
// Do some work.
rAF = requestAnimationFrame(draw);
};
rAF = requestAnimationFrame(draw);
When you do this:
setTimeout(cancelAnimationFrame, 1000, rAF);
you pass three values to setTimeout
: a function, a number, and another number.
When this statement is executed the call is evaluated, meaning that first, the setTimeout
identifier is resolved to a function reference.
Second, the three arguments are evaluated: the cancelAnimationFrame
identifier is resolved to a function reference, then the number literal is a number primitive, then the rAF
identifier is resolved to another number primitive.
Then, the call is performed.
That’s all that setTimeout
sees.
In JavaScript, you cannot pass a reference to a number, like you can in C, for example.
Let’s assume rAF
is initially 1
.
Over the course of one second, rAF
has been repeatedly incremented and eventually reaches the value 61
or so.
Since you register the setTimeout
at the start, the statement
setTimeout(cancelAnimationFrame, 1000, rAF);
is equivalent to
setTimeout(cancelAnimationFrame, 1000, 1);
However, the statement
setTimeout(() => cancelAnimationFrame(rAF), 1000);
is not equivalent to
setTimeout(() => cancelAnimationFrame(1), 1000);
The function bodies are only evaluated when they are called.
This means, JS doesn’t “peek inside the functions” and attempt to evaluate variables.
That statement essentially means “call some function with some other function and the number 1000 as arguments”.
When the one second is over and it’s time to cancel the animation frame, setTimeout
executes its callback.
If the callback is () => cancelAnimationFrame(rAF)
, then it’s executed, so the function body is evaluated: cancelAnimationFrame(rAF)
is equivalent to cancelAnimationFrame(61)
.
However, in the non-working case, cancelAnimationFrame
stays the same, the argument 1
(equivalent to rAF
at the time setTimeout
was originally called) stays the same.
You can’t cancel frame 1 when you’re already at frame 61.
And setTimeout(alert, 1000, "Hello");
works, of course, because "Hello"
is static, is only evaluated once, never changes.
Related
Here’s a more general situation where this behavior can be examined:
let greeting = "Hello";
const greet = (theGreeting) => console.log(`${theGreeting}, world!`);
const boundGreeting = greet.bind(null, greeting);
greeting = "Goodbye";
boundGreeting(); // Logs "Hello, world!".
greet(greeting); // Logs "Goodbye, world!".
Why does wrapping a callback in an anonymous function change the meaning of 'this'?
Using an anonymous function wraps MyObj in a closure. That closure's lexical scope (execution context) is now localized to the closure. So this
is localized to the closure (and MyObj) as well.
You can discover that by using a debugger with a break point set on the callback()
call.
This image shows the variable structure with the closure in place:
Without the function wrapper, the lexical scope is the same scope as the higherOrder()
function - which is the global scope. Again, this is demonstrated with a break point on the same line of code (note lack of closure):
Note: this code is run in node - so no Window object here.
Rider - keep anonymous function block argument on same line as function call
These settings should work (File | Settings | Editor | Code Style | C#):
- On "Braces Layout" tab change "Anonymous method declaration" to "At
end of line" - On "Line Breaks and Wrapping" tab uncheck "Prefer wrap
before "(" in invocation" and "Prefer wrap before ")" in invocation"
JavaScript anonymous function immediate invocation/execution (expression vs. declaration)
The first two cases show function expressions, and can appear anywhere an expression like (1+1
or x*f(4)
) would appear. Just like how 1+1
, evaluates to 2
, these expressions evaluate to a corresponding function.
The third case is a function declation statement, and can appear anywhere you can have other statements (like an if
or while
statement).
There is not much point in trying to declare an anonymous function via a Funcion declaration statements, since otherwise noone would get a reference to the function afterwards.
The reason you need the opening (
or the var x =
like in the first two cases is that they force next bit to be parsed in an expression context. (just think how you cant do var x = if ...
, for example). If you just put the function
as the first thing it will be parsed as the declaration statement you don't want.
Reason behind this self invoking anonymous function variant
.call(this)
(was actually just ()
until I changed it) ensures your top level this
to be consistent through strict mode, --bare
option and/or the running environment (where top level this
doesn't point to global object).
Why can't I use an anonymous function expression for accessing an array index position?
() => 0
returns a function, not the value returned when called.
You need to invoke the function instead:
const arr = ["one", "two", "three"];
console.log(arr[(() => 0)()]);
Related Topics
How to Check If a Variable Is an Array in JavaScript
JavaScript Function to Add X Months to a Date
Change the Url in the Browser Without Loading the New Page Using JavaScript
Jquery Event That Triggers After CSS Is Loaded
How to Animate a Progressive Drawing of Svg Path
CSS Transition Doesn't Work with Top, Bottom, Left, Right
Node.Js - How to Set Environment Variables in Code
Mocha/Chai Expect.To.Throw Not Catching Thrown Errors
Jqgrid Server Side Error Message/Validation Handling
Why Do You Need to Invoke an Anonymous Function on the Same Line
Object Destructuring Without Var, Let or Const
Read a File One Line At a Time in Node.Js
How to Fetch the Value of a Non-Standard CSS Property via JavaScript
Resetting the Opacity of a Child Element - Maple Browser (Samsung Tv App)
Full Height of a HTML Element (Div) Including Border, Padding and Margin