Why are Javascript Functions declared in different ways - javascript

Apologies if this seems like a beginner question, I am currently learning Javascript and have come across different ways of structuring function declarations. An example below
function mapStateToProps(state) {
console.log(state);
}
const mapStateToProps = state => {
console.log(state);
}
What is the benefit of using one or the other; in which situation would you use one over the other?

Arrow functions are the new ES2015 syntax, for me the main difference is changing this context you may read about it here https://medium.com/#thejasonfile/es5-functions-vs-es6-fat-arrow-functions-864033baa1a

The first example is a function declaration and the second example is a function expression. The second example you provided only serves to provide more concise JavaScript code to the first example and doesn't really capture the idea of your question of when to use ES6 arrow functions over function declarations. In other words your example, is just syntactic sugar, in your examples, nothing is really solved, just more concise code.
A better example is the following:
const team = {
members: ['Dolly', 'Billy'],
teamName: 'Hacking Crew',
teamSummary: function() {
return this.members.map(function(member) {
return `${member} is on team ${this.teamName}`;
});
}
};
console.log(team.teamSummary());
Run this snippet and you will see the error. Now, this error does not have to be solved with the arrow function, there are a couple of ways to solve it, but your question of in which situation would you use one over the other, this is a good use case for using an arrow function to solve this error.
Before I provide the solution, understand that fat arrow functions make use of what is called the lexical this. I will provide the refactor below and then unpack my previous sentence:
const team = {
members: ['Dolly', 'Billy'],
teamName: 'Hacking Crew',
teamSummary: function() {
return this.members.map((member) => {
return `${member} is on team ${this.teamName}`;
});
}
};
console.log(team.teamSummary());
Lexical means the placement of this term depends on how its interpreted or how its evaluated. So, depending on where we are placing the word this will change when using a fat arrow function.
When we use a fat arrow function and make reference to this inside of it this is automatically set equal to this in the surrounding context which in this code snippet is the team object.
So if lieu of using .bind(this) and having to cache a reference to this, you can replace fat arrow function as a solution.

Related

Question about comparing two functions by stringifying them

I came across this excerpt while reading Chapter 2 of "You Don't Know JS Yet".
But beware, it's more complicated than you'll assume. For example, how might you determine if two function references are "structurally equivalent"? Even stringifying to compare their source code text wouldn't take into account things like closure.
I just want to make sure if I understand correctly on what the author meant by "closure". I'm thinking of this example:
function x() {
console.log('Hello');
}
const foo = x;
function y() {
const bar = x;
if(foo.toString() === bar.toString()) { // returns true but the closure of foo and bar is different
// do something
}
}
Also, under what circumstances we need to compare two functions? Thanks.
Here is an example of two functions that look the same yet will behave differently because of their closure:
const what="great",
fun1=()=>console.log(`This is ${what}!`);
{ // this block will have its own closure
const what="stupid",
fun2=()=>console.log(`This is ${what}!`);
console.log(fun1.toString()==fun2.toString());
fun1();
fun2();
}
The author means that closure is the data that a function carries with it, including the variables from its surrounding scope that are used in its body. In the example you gave, even though the two functions foo and bar have the same source code (as indicated by the toString() comparison), they are not structurally equivalent because they have different closure values.
As for when to compare two functions, you might need to compare two functions in certain scenarios, such as when you want to determine if two functions have the same behavior, if they have the same closure, or if they are bound to the same execution context.
As far as I can tell, the author is saying "closure" as a reference to scope. I think you are correct.
As for the comparison of two functions, the most obvious case that comes to mind is comparing the time and space complexity performance of two functions that perform the same overall task. However, in regards to the authors 'structurally equivalent' notion, I don't know.

Differences Between Named and Unnamed Anonymous Javascript Functions

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.

Decorators on functions

I see that babel.js decorators (available in "stage 1") implement the spec at https://github.com/wycats/javascript-decorators. It appears that decorators are limited to (1) classes, (2) accessors, and (3) methods. In my case, I want to use decorators on plain old functions, as in
#chainable
function foo() { }
where (just an example)
function chainable(fn) {
return function() {
fn.apply(this, arguments);
return this;
};
}
I don't see any logical reason why decorators should not be able to apply to functions. My question is, is there some way to accomplish this? Or is there some good reason why functions cannot be decorated?
It turns out there is an issue raised for this at https://github.com/wycats/javascript-decorators/issues/4.
To execute a decorator, you evaluate an expression and doing that prevents hoisting (even for a variable declaration, the right-hand side of an assignment stays put). Therefore, it is not compatible with function declarations being hoisted.
As a work-around, I suggested that function expressions, generator function expressions and arrow functions could be enabled to be decorated:
const func = #someDecorator('abc') (x, y) => { return x + y };
Alas, that wasn’t met with much enthusiasm: Decorators for functions
You certainly have a point here.
But as neo_blackcap pointed out, function decorator are not part of the ES7 decorators draft.
So, the best thing you can do is to start discussion on the corresponding tracker to attract community attention to your proposal.
ES7 decorators are on their first stage of development second stage of development, meaning that their API is still under development and could undergo any change.
I think the problem is function decorator has not been ES7 draft.
Of course, you still can implement your function decorator by yourself

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.

Declaring functions in JavaScript [duplicate]

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed last year.
What's the difference between these two ways of declaring a function?
function someFunc() { ... }
var someFunc = function() { ... }
I'm not asking in the technical sense. I'm not asking which is better for readability, or which style is preferred.
I am on different opinion with most of the people here. Technically this syntax may mean the same for declaring functions both ways
(I stand incorrect on my last statement. I read up on a diff post why they are technically diff and I'll add in the end, why)
; but the way they play a role in evolving patterns is massive. I would highly recommend "Javascript: The Good Parts" by Doughlas Crockford.
But to prove my point in a subtle and a simple manner; here is a small example.
//Global function existing to serve everyone
function swearOutLoud(swearWord) {
alert("You "+ swearWord);
}
//global functions' territory ends here
//here is mr. spongebob. He is very passionate about his objects; but he's a bit rude.
var spongeBob = {
name : "squarePants",
swear : function(swearWord) {
name = "spongy";
alert("You "+ swearWord);
return this;
}
}
//finally spongebob learns good manners too. EVOLUTION!
spongeBob.apologize = function() {
alert("Hey " + this.name + ", I'm sorry man!");
return this;
}
//Ask spongebob to swear and then apologize in one go (CASCADING EFFECT!!)
alert(spongeBob.swear("twit").apologize());
if you look at the code above I declared a function with a name swearOutLoud. Which would take a swear word from any object or a call and will give you the output. It can do operations on any object using the "this" parameter that is passed to it and the arguments.
However second declaration is declared as an attribute of object called "spongeBob". This is important to note; as here I am moving towards an object driven behavior. While I am also maintaining "cascading effect" as I return "this" if i have nothing else to return.
Somthing similar is done in jquery; and this cascading pattern is important if you are trying to write a framework or something. You'll link it to Builder design pattern also.
But with functions declared as an attributes of an object I am able to achieve an object centric behavior which leads to a better programming paradigm. Unless designed well; individual functions declared outside with global access lead to a non-object oriented way of coding. I somehow prefer the latter.
To see cascading in effect, look at the last statement where you can ask spongebob to swear and apologize at once; even though apologize was added as an attribute later on.
I hope I make my point clear. The difference from a technical perspective may be small; but from design and code evolution perspective it's huge and makes a world of a difference.
But thats just me! Take it or leave it. :)
EDIT:
So both the calls are technically different; because a named declaration is tied to global namespace and is defined at parse time. So can be called even before the function is declared.
//success
swearOutLoud("Damn");
function swearOutLoud(swearWord) {
alert("You " + swearWord)
}
Above code will work properly. But code below will not.
swear("Damn!");
var swear = function(swearWord) {
console.log(swearWord);
}
One advantage of using function someFunc() { ... } is that the function name appears in Firebug debugger. Functions that are declared the other way (var someFunc = function() { ... }) come up as anonymous.
Actually, the difference is that the second declaration gives us the ability to declare functions like this making it possible to have a function as a property for an object :
var myObject=new Object();
myObject.someFunc=function() { ... };
Style wise the second example is more consistent with other common ways to declare functions and therefore it could be argued that it is more readable
this.someFunc = function() { ... }
...
someFunc: function() { ... },
However, as also mentioned it's anonymous and therefore the name does not appear when profiling.
Another way to declare the function is as follows which gets you the best of both worlds
var someFunc = function someFunc() { ... }
Another difference is that, on most browsers, the latter allows you to define different implementations depending on circumstances, while the former won't. Say you wanted cross-browser event subscription. If you tried to define a addEventListenerTo function thusly:
if (document.addEventListener) {
function addEventListenerTo(target, event, listener) {
....
}
} else if (document.attachEvent) {
function addEventListenerTo(target, event, listener) {
....
}
} else {
function addEventListenerTo(target, event, listener) {
....
}
}
on some browsers, all the functions end up being parsed, with the last one taking precedence. Result: the above just doesn't work. Assigning anonymous functions to variables, however, will work. You can also apply functional and basic aspect oriented programming techniques using anonymous functions assigned to variables.
var fib = memoize(function (n) {
if (n < 0) return 0;
if (n < 2) return 1;
return fib(n-1) + fib(n-2);
});
...
// patch the $ library function
if (...) {
$ = around($, fixArg, fixResult);
}
It is both true that the first form:
function test() { }
is a more recognized syntax and that the second form:
var test = function() { ... }
allows you to control the scope of the function (through the use of var; without it, it would be global anyway).
And you can even do both:
var test = function test() { ... test(); ... }
This allows you to define a recursive function in the second form.
For readability, I'd say the first is clearly better. A future maintenance programmer, even assuming they're familiar enough with javascript to know many of the finer points coming up in this thread, are going to assume the first format.
For example, if they should some day want to ctrl-f to search for the definition of your function to see what's happening in there, are they going to first search for someFunc = function() or function someFunc()?
Also, to get downright typographical about it (since we're talking readablity) readers are often scanning the text quickly, and would be more inclined to skip over a line that starts with "var" if they're looking for a function definition.
I know this is a non-technical answer, but it's harder for humans to read code than computers.
When you write
function Test() {
}
JavaScript is really creating a property to which it assigns the function object that once called will execute the code reported in the function definition. The property is attached to the object window, or to the object that contains the function definition.

Categories

Resources