Differences Between Named and Unnamed Anonymous Javascript Functions - javascript

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.

Related

Why pass an entire function definition as an argument instead of just the function name which can be reused?

The former seems to be much more "hip" in JavaScript, and I don't understand why.
Edit: in response to this question possibly being a duplicate, my interest is why, not how. And another question asking only about "closures" in the title wouldn't catch the eye of the person who hasn't made the link between this and closures yet.
tl;dr: Because many functions are actually not reused.
I think you answered your own question:
... instead of just the function name which can be reused?
Many of these are "one-off" cases. The line of code is executed once and the passed function doesn't have to be reused.
For example, if I want to bind an event handler to a body and I don't intend to reuse the event handler anywhere, why should I write
function bodyEventHandler() {}
document.body.addEventListener('click', bodyEventHandler);
and unnecessarily pollute the current scope with bodyEventHandler?
document.body.addEventListener('click', function() {...});
has the same effect, doesn't pollute the scope and keeps the function definition where it is used.
JavaScript is very much event-driven, and most event handlers are actually not going to be reused anywhere else.
Keeping the function definition where the function is used is also a common reason IMO. Some functions are either very simple, but it may not be easy to give them descriptive names.
E.g. if you are not familiar with the term "pluck", would you understand what
var names = users.map(pluck('name'));
really does? Maybe you can infer it from the other variables names.
However,
var names = users.map(function(user) { return user.name; });
makes it immediately clear.
In fact, you will see these even more often, now that ECMAScript 6 introduces arrow functions, which are like lambda functions in other languages:
var names = users.map(user => user.name);
I also think you have a misconception of what exactly happens under the hood when you pass a function:
... pass an entire function definition as an argument instead of just the function name ...
foo(bar) does not pass the name "bar" to foo. It passes the function object that is referenced by the variable bar. That is no different from foo(function() { ... }). The only difference is that we are not (temporarily) storing the function in a variable.

why is it necessary to wrap function call in a function body

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.

Javascript: explain this syntax to me

JS newbie here, I've been looking through some code recently which uses syntax I'm not too familiar with. Here's an example, followed by my questions:
function Group(args) {
this.showItem = showItem;
function showItem(args) {
...
}
}
var group = new Group (args);
Questions:
As I understand it creating function Group and then instantiating via group = new Group is essentially prototypal equivalent of defining a class and then instantiating an object of that class. Is that correct?
Regarding the properties (methods?) of Group, what is the above syntax for showItem called? Why not just define it like:
this.showItem = function(args){...};
Would changing the code to the above change any different behavior?
If you did define it as above, what is that syntax called?
The Group function is being used as a constructor; your intuition is basically correct.
There is no good reason not to use an anonymous function expression like this.showItem = function(args){...};, unless you wanted to reuse the local variable showItem.
I'm not sure which syntax you mean. The function(args){...} is an anonymous function expression, and the this.showItem is referring to a member of the object this. Taken all together, I suppose you could call it "setting a member function of an object".
Bonus tip (which maybe you already knew?): the reason you can use showItem before its definition is due to function hoisting.
EDIT:
You seem to be asking about function expressions versus function declarations as well as named versus anonymous functions. The primary differences are:
Function declarations always stand on their own. They are never part of another operation, e.g. assignment. Your first example uses the function declaration function showItem(args) {...}. Function expressions are used as an expression in some operation (e.g., assignment, passed as an argument, etc.). Your second case uses a function expression.
Function declarations are hoisted to the top of the current function scope, so showItem in your first case is defined and contains the function when you use it in your assignment operation. Function expressions are not hoisted.
Function declarations are always named. Function expressions may be named or anonymous. When a function is defined with a name, that name is accessible as the name property of the function object. A function's name is immutable and independent of any variables that hold a reference to the function. Also, code inside the function body can refer to the function by its name as a local variable (which is sometimes useful for recursion inside named function expressions).
To review:
Function definition: function showItems(args){...};
Anonymous function expression: this.showItems = function(args){...};
Named function expression: this.showItems = function showItemsName(args){...};
In the first case, there is a local variable called showItems defined and the definition of showItems is hoisted to the top. The difference between the latter two cases is that this.showItems.name will be "showItemsName" for the third case and undefined for the second. Also, showItemsName will be a local variable within the function body of the third function that holds a reference to the function object.
The Group function is used as a constructor. However, the way this is done is a bit inefficient. What this code is doing is creating a new function and attaching it to the constructed object. He may be doing this because he wants to create a closure (i.e. use a variable only present in the namespace of the constructor), but absent that reason it's better to do this:
function Group(args){}
Group.prototype.showItem = function(args) {};
This way the same showItem function is shared among all objects constructed by Group via the prototype chain.
The benefit of using the original code vs an anonymous function is that the function has a name--this is a great help in debugging because reading a traceback full of anonymous function calls is no fun! To expand, there are three types of things that use the function keyword:
Function declarations When at the top level of a program or a function (i.e., of something that creates/has its own namespace), you may declare a function with a name. (The name stays with the function object throughout the program and will appear in tracebacks.) This is function showItem(args) {} in your example. (Note that this is only a function declaration at the top level of a file or function. There's a very similar thing I'll get to last.) By convention most people seem to omit semicolons after these.
Function expressions When part of an expression (such as assignment, return, etc), it is a function expression. The identifier part of the function expression is optional, so these are both function expressions:
var myfunc1 = function(){};
var myfunc2 = function MyFunctionName(){};
The second form is called a "named function expression". The great benefit of using this form is that MyFunctionName is no longer an anonymous function--this name will be attached to the function and will show up in tracebacks (for example). However there is a very serious bug in JScript (IE <= 8) that makes using these problematic. Read the article I linked above for details.
Finally, there is a common extension syntax called function statements. These look exactly like function declarations, except they are not top level! For example:
function() {
function foo(){} // function declaration
if (1) {
function bar(){} // function STATEMENT--not standard JS!
}
}
You should not rely on this extension, but should do this instead:
function() {
var bar;
if (1) {
bar = function bar(){};
}
}
this.showItem = function(){} would be called a "function expression in an assignment", and the original code is just using a "function declaration".

Grammar of Self Invoking Anonymous Functions

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.

Is it good to write javascript functions inside functions and not use 'new' on the main function?

I now know this works:
function outerfunction(arg1, arg2, arg3) {
var others;
//Some code
innerFunction();
function innerFunction() {
//do some stuff
//I have access to the args and vars of the outerFunction also I can limit the scope of vars in the innerFunction..!
}
//Also
$.ajax({
success : secondInnerFunction;
});
function secondInnerFunction() {
// Has all the same benefits!
}
}
outerFunction();
So, I am not doing a 'new' on the outerFunction, but I am using it as an object! How correct is this, semantically?
There doesn't appear to be anything wrong with what you're doing. new is used to construct a new object from a function that is intended as a constructor function. Without new, no object is created; the function just executes and returns the result.
I assume you're confused about the closure, and how the functions and other variables belonging to the function scope are kept alive after the function exits. If that's the case, I suggest you take a look at the jibbering JavaScript FAQ.
You are not using the outer function as an object. You are using it to provide a closure. The border line is, admittedly, thin, but in this case, you are far away from objects, since you do not pass around any kind of handle to some more generic code invoking methods, all you do is limiting the scope of some variables to the code that needs to be able to see them.
JFTR, there is really no need to give the outer function a name. Just invoke it:
(function() { // just for variable scoping
var others;
...
})()
I do this sort of thing all the time. Yes - javascript blurs the boundary between objects and functions somewhat. Or perhaps, more correctly, a javascript function is just an object that is callable. You would only really use the 'new' prefix if you wanted to have multiple instances of the function. My only suggestion here is that its usually considered good practice to call a function after you've declared it (you are calling the innerFunction before it has been declared) - although that could be considered nit-picking.
This is a valid example.
Functions in JavaScript are first order objects. They can be passed as an argument, returned from a function or even set to a variable. Therefore they are called 'lambda'.
So when you are directly using this function (without new keyword) you are directly dealing with the function as an object. When u are using new keyword, you are dealing with an object instance of the function.

Categories

Resources