From what I have read from other topics about the issuse SIAFs or Self Invoking Anonymous Functions are simply there to serve as a container, and it limits the scope of variables (from what I have learnt). Now, the question is, why can I do this:
$("ul>li").click((function(){
}));
But not add another SIAF after it? Like so:
$("ul>li").click((function(){
}));
(function(){
});
It is weird to me, as this, just the SIAF on its own gives me no errors in the IDE:
$("ul>li").click((function(){
}));
(function(){
});
This:
(function() { .. });
is a no-op expression, and in particular it does not involve a function call. A function object is instantiated but it's not used in any way.
This:
(function() { ... })();
does do something, because the trailing () causes the function to be invoked. (It doesn't invoke itself.)
In JavaScript, a reference to a function is just a value, and a function is just an object (well, a special object). When a reference to a function is followed by a parenthesized list of values, then that's a function call. It doesn't matter where the reference to the function comes from. (Where it comes from can affect the semantics of the function call, but not the basic fact of the function call itself.)
edit — the terminology "self-invoking function expression" has gained some currency. I won't wade into a dispute, but in my opinion it's less accurate than the alternative "immediately-invoked function expression" because really a function can't invoke itself externally. It can include a call to itself, but that's a different thing entirely. However I understand the spirit of the term and I think it's harmless.
Related
Normally, in Javascript, when I want to pass an anonymous/inline function as an argument to another function, I do one of the following.
someFunctionCall(function() {
//...
});
someFunctionCall( () => {
//...
});
However, I've recently inherited a codebase that uses named function as inline arguments, like this
someFunctionCall(function foo() {
//...
});
I've never seen this syntax before. The function still seems to be anonymous -- there's no foo function defined in either the calling or called scope. Is this just a matter of style, or can using a named function (foo above) as an anonymous function change the behavior or state of that program?
This is specifically for a NodeJS (not a browser based program) program, and I'm specifically interested in behavior specific to using functions as parameters. That said information from behavior across platforms and runtimes is welcome.
There are at least three advantages of using named function expressions instead of anonymous function expressions.
Makes debugging easier as the function name shows up in call hierarchy.
The function name is accessible in the inner scope of the function, so it can be used for recursion
The function name itself acts like a self documentation of what the function is doing instead of reading the code.
Using those "named anonymous functions" won't change the behavior but will show the function name in stack traces which is very useful. Also the function gets callable within itself that way.
I'll give an example
Case 1:
var obj = {count: 0, counter: ()=> {this.count+=1;}}
If you do console.log(obj.count) you'll get 0
Case 2:
var obj = {count: 0, counter (){this.count+=1;}}
In 2nd case if you do console.log(obj.count) value will be one.
Hope you understood by now. Lamda expressions cannot access values with reference of this object. It can only access variables with global reference.
In case 1 if you want to make it work with lamba you have to use obj.count+=1 with name has reference.
And rest of the JavaScript function implementation remains same there is not much difference.
I came across following code. Can someone explain it to me? I'm not sure how it'll be executed? Is there any specific reason to write it like this?
var foo = (function() {
// ...bunch of code
return function(param1) {
// ...bunch of code
return var1;
}
})();
EDIT: I know that the outer part (...)();, is executed immediately. What I'm not sure is why it is assigned to variable foo. I guess when the IIFE is executed it'll only execute the return ... inner code. But when the code inside that inner function ... is executed? When the line return var1 is executed? I hope now it is clear as water
What you're seeing is a JS idiom called Immediately-invoked function expression. Extracted from Wikipedia:
An immediately-invoked function expression (or IIFE, pronounced "iffy"1) is a JavaScript programming language idiom which produces a lexical scope using JavaScript's function scoping. Immediately-invoked function expressions can be used to avoid variable hoisting from within blocks, protect against polluting the global environment and simultaneously allow public access to methods while retaining privacy for variables defined within the function. This concept has been referred to as a self-executing anonymous function,[2] but Ben Alman introduced the term IIFE as a more semantically accurate term for the idiom, shortly after its discussion arose on comp.lang.javascript
As can be read in the extract, it's main purpose is mainly to avoid polluting the global namespace though it is also heavily used to take advantage of closure.
UPDATE
In Javascript, functions are first-class objects. This means that they can be passed around like any other object would be. They can also be assigned to variables.
The function you mention is just returning a function (like it could be returning an int or an object literal) that gets assigned to the variable foo. foo then has the reference to the function and can be executed like any normal function would be (i.e foo('a') ).
By the way, a function that returns another function or takes one or more functions as arguments is called higher-order function.
Hope this clarifies things.
The reason would be difficult to guess, but it could be for obfuscation, to avoid plagiarism
The execution will go like:
var foo will receive the result of a function call (the parenthesis after the assignment contain a function declaration, and right after those, the other pair of parenthesis are those function arguments)
that 1st anonymous function will execute the bunch of code, then return what the other function evaluates
the 2nd anonymous function well execute the other bunch of code and finally return var1
ergo: it is the same of executing bunches of code, store the result in var1 and then var foo = var1, simplifying for explanation purpose
Newbie jQuery / Javascript question here
I see functions written in the following fashion:
some_function = function(event) {
}
My question is: What is meant by that event argument? Is it optional? What if I want to have two additional parameters, X and Y, what would the signature look like? When I call the function now, I can just call it like some_function(); and it works fine (which leads me to believe that it's optional). However, how will that change when I have two additional arguments like X and Y? Can I just call it like some_function(myX, myY) ?
Thanks!
There are two ways to instantiate a function in JavaScript. They both look the same, but their meanings aren't quite the same.
What you've posted is a function instantiation as part of an expression in the language. In that form, the syntax is
function name ( p1, p2, ... ) { body }
The "name" and the parameters are optional; the keyword function and the parentheses are required. (There are some obscure issues with using a name in this case, in some browsers; it's getting to be less of a problem.)
The effect of that is to create a new function object. The reference to the object participates in the expression just like any other value (well, like any other reference to an object). Because it's a function, the reference can also be used to call the function and cause its code ("body") to execute, just like you'd expect. (It wouldn't be much of a function if you couldn't!)
The other way a function can be instantiated is with a function declaration statement, which looks, surprisingly, exactly the same (except that "name" is required). The difference involves where exactly in your code the keyword function appears:
If the keyword function is the first thing in a new statement, then you've got a function declaration and the "name" is required. The statement is not an expression statement in this case, and the only thing the statement does is instantiate the function and bind a reference to the function to "name" more or less as if "name" were a local variable (or global if in the global scope).
If the keyword function appears anywhere else in an expression (either an expression statement, or an expression buried inside some other context, like the top of a for or while loop statement), then it's a function instantiation expression.
Now, regardless of how a function is "born", once you've got a reference to the function you can call it and pass as many parameters as you like.
I don't know personally how the trend started, or whether it's even something that should be considered a trend, but it's fairly common to see local functions instantiated with code like this (and like what you posted):
var some_function = function( arg1, arg2 ) {
/* some code */
};
That's an example of a function instantiation in an expression. The net effect is that the symbol "some_function" is bound to the newly-created function. There are slight nitpicky differences, however, between the way that name is bound to the function from the (almost) equivalent function declaration:
function some_function( arg1, arg2 ) {
/* some code */
};
One simple reason that the second way (function declaration statement) is a little better is that the name of the function will show up in stack traces. Of course, one could achieve that with the redundant-looking:
var some_function = function some_function( arg1, arg2 ) {
/* some function */
};
I don't really know why you'd want to do that, but it'd work, except in some naughty environments.
That code snippet is a little vague, however I can answer, in general, your questions.
The event argument, in the code you provided, is just what that function will use to reference the first parameter that is passed to the function from whatever-other code calls it. For example, if you had code that called your some_function function, and passed it a string "hello world!", the call would look something like:
obj.some_function("hello world!")
Inside of the some_function function, the variable event would contain "hello world!". Also, you could change your some_function signature to be: some_function(blah) and it would be all the same, you would just use blah to reference the parameter instead of event. The variable name you choose for parameters is entirely up to you, though you want to make sure you don't use language-reserved names (like in, for, continue, break, etc)
Technically all parameters are optional for a JavaScript function, unless the internal code of the function enforces the parameters (i.e. it may return or throw an error if a parameter is missing.
#Pointy answered the other point I was going to make...that the code you provided is defining that function as an expression. I use that syntax when I'm creating a function that is an attribute of an object (which is why my above code has obj. at the beginning.
I often see something like the following in JavaScript:
$("#sendButton").click(function() {
sendForm();
}
Why is it necessary to wrap the call to sendForm() inside a function? I would think that doing it like this would be more readable and less typing.
$("#sendButton").click(sendForm);
What are the advantages/disadvantages to each approach? thanks!
There's typically two cases where you'd want to use the former over the latter:
If you need to do any post-processing to the arguments before calling your function.
If you're calling a method on an object, the scope (this reference) will be different if you use the second form
For example:
MyClass = function(){
this.baz = 1;
};
MyClass.prototype.handle = function(){
console.log(this.baz);
};
var o = new MyClass();
$('#foo').click(o.handle);
$('#foo').click(function(){
o.handle();
});
Console output:
undefined
1
Probably one too many answers by now, but the difference between the two is the value of this, namely the scope, entering sendForm. (Also different will be the arguments.) Let me explain.
According to the JavaScript specification, calling a function like this: sendForm(); invokes the function with no context object. This is a JavaScript given.
However, when you pass a function as an argument, like this: $(...).click(sendForm), you simply pass a reference to the function for later invocation. You are not invoking that function just yet, but simply passing it around just like an object reference. You only invoke functions if the () follows them (with the exception of call and apply, discussed later). In any case, if and when someone eventually calls this function, that someone can choose what scope to call the function with.
In our case, that someone is jQuery. When you pass your function into $(...).click(), jQuery will later invoke the function and set the scope (this) to the HTML element target of the click event. You can try it: $(...).click(function() { alert(this); });, will get you a string representing a HTML element.
So if you give jQuery a reference to an anonymous function that says sendForm(), jQuery will set the scope when calling that function, and that function will then call sendForm without scope. In essence, it will clear the this. Try it: $(...).click(function() { (function() { alert(this); })(); });. Here, we have an anonymous function calling an anonymous function. We need the parentheses around the inner anonymous function so that the () applies to the function.
If instead you give jQuery a reference to the named function sendForm, jQuery will invoke this function directly and give it the scope that it promises to always give.
So the answer to your question becomes more obvious now: if you need this to point to the element target of the click when you start work in sendForm, use .click(sendForm). Otherwise, both work just as well. You probably don't need this, so skip the anonymous function.
For those curious, scope can be forced by using the JavaScript standard apply or call (see this for differences between the two). Scope is also assigned when using the dot operator, like in: obj.func, which asks of JavaScript to call a function with this pointing to obj. (So in theory you could force obj to be the scope when calling a function by doing something like: obj.foo = (reference to function); obj.foo(); delete obj.foo; but this is a pretty ugly way of using apply.
Function apply, used by jQuery to call your click handler with scope, can also force arguments on the function call, and in fact jQuery does pass arguments to its click handlers. Therefore, there is another difference between the two cases: arguments, not only scope, get lost when you call sendForm from an anonymous function and pass no parameters.
Here you are defining an anonymous event handler that could call multiple functions inline. It's dirty and tough to debug, but people do it because they are lazy and they can.
It would also work like your second example (how I define event handlers):
$("#sendButton").click(sendForm)
Something you get by defining your event handlers inline is the ability to pass event data to multiple functions and you get this scoped to the event object:
$("#sendButton").click(function(event) {
sendForm();
doSomethingElse(event);
andAnotherThing(event);
// say #sendButton is an image or has some data attributes
var myButtonSrc = $(this).attr("src");
var myData = $(this).data("someData");
});
If all you are doing is calling sendForm, then there isn't much difference, in the end, between the two examples you included.
$("#sendButton").click(function(event) {
if(event.someProperty) { /* ... */ }
else { sendForm({data: event.target, important: 'yes'}); }
}
However, in the above case, we could handle arguments passed to the callback from click(), but if the sendForm function is already equipped to handle this, then there's no reason why you wouldn't place sendForm as the callback argument if that is truly all you are doing.
function sendForm(event) {
// Do something meaningful here.
}
$("#sendButton").click(sendForm);
Note that it is up to you where you handle the differing layers of logic in your program; you may have encapsulated certain generic functionality in a sendForm function then have a sendFormCallback which you pass to these sorts of function which handle the interim business of event/callback processing before calling sendForm itself.
If you are working in a callback-heavy environment, it would be wise to separate significant functionality from the callback triggers themselves to avoid callback hell and promote maintainability and readability in your source code.
It's just to lock scope. When you wrap that sendForm() in the anonymous function that closes over the current scope. In other words, the this will be kept with it. If you just pass sendForm then any calls to this will come from the calling scope.
This is a good question for learning about scope in javascript, and questioning conventions.
Nope, that second example is perfectly valid.
99.9% of jQuery examples use the first notation, that doesn't mean you need to forget basic JavaScript syntax.
There is a JSLint option, one of The Good Parts in fact, that "[requires] parens around immediate invocations," meaning that the construction
(function () {
// ...
})();
would instead need to be written as
(function () {
// ...
}());
My question is this -- can anyone explain why this second form might be considered better? Is it more resilient? Less error-prone? What advantage does it have over the first form?
Since asking this question, I have come to understand the importance of having a clear visual distinction between function values and the values of functions. Consider the case where the result of immediate invocation is the right-hand side of an assignment expression:
var someVar = (function () {
// ...
}());
Though the outermost parentheses are syntactically unnecessary, the opening parenthesis gives an up-front indication that the value being assigned is not the function itself but rather the result of the function being invoked.
This is similar to Crockford's advice regarding capitalization of constructor functions -- it is meant to serve as a visual cue to anyone looking at the source code.
From Douglass Crockford's style convention guide: (search for "invoked immediately")
When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.
So, basically, he feels it makes more clear the distinction between function values, and the values of functions. So, it's an stylistic matter, not really a substantive difference in the code itself.
updated reference, old PPT no longer exists
Immediately Called Anonymous Functions get wrapped it in parens because:
They are function expressions and leaving parens out would cause it to be interpreted as a function declaration which is a syntax error.
Function expressions cannot start with the word function.
When assigning the function expression to a variable, the function itself is not returned, the return value of the function is returned, hence the parens evaluate what's inside them and produce a value. when the function is executed, and the trailing parens ..}() cause the function to execute immediately.
Or, use:
void function () {
...
} ()