What's the general difference between these two styles of handling .catch blocks in Promises:
...
.catch(e => myMethod(e))
...
.catch(myMethod)
What does a Promise's .catch pass to the received method?
e.g. Can there be additional arguments?
In both cases, there is only one argument.
There's no fundamental difference between these two styles, except that an arrow function behaves differently than a real function, especially this will be undefined or window (depending on whether strict mode is enabled or not) with a function, and with an arrow function it's the same this as the context in which it is declared.
From this MDN Catch Syntax documentation:
This .catch has one argument:
reason:
The rejection reason.
From this MDN Arrow Function documentation:
An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords. Arrow function expressions are ill suited as methods, and they cannot be used as constructors.
In catch(e => myMethod(e)), you are passing an anonymous function which takes a parameter e and calls myMethod(e)
In catch(myMethod), you are directly passing your myMethod instead of that anonymous function (in above case), which takes a parameter e.
So, both are same. And the parameter passed e is the "reason" for being rejected.
Related
What is the difference between these functions:
callback(x: string[], y: string[]){
console.log(x.concat(y).join(', '));
}
and
(c,d) => console.log(c.concat(d).join(', '))
?
From theoretical view first is a standard function, the second is so called arrow function.
From the Documentation, arrow functions differs from standard functions in this criterias
An arrow function expression has a shorter syntax than a function
expression and does not have its own this, arguments, super, or
new.target. These function expressions are best suited for non-method
functions, and they cannot be used as constructors.
Arrow functions does not have their own this, they get it from the
upper scope, where are defined.
They don't have arguments object inside the body, which has every
standard function and via that you can access passed in arguments.
You can create an object via arrow function - see point 1.
From Typescript view, same as above and also that you haven't provide argument types for the arrow function. Also be aware that you mistyped argument name in the arrow function.
The first is TypeScript and performs type checking on the inputs.
The second is JavaScript and throws an error because the variable names in the arguments don't match the variable names used in the function. (That error aside, it does the same thing, just without the type checking).
I'm brand new to JavaScript and currently learning about writing functions shorthand. I just came across this while studying:
const groceries = (groceryItem) => ' - ' + groceryItem;
Is it acceptable/best practice in the real world to write functions like this? (no return, no brackets) I notice that it may be annoying to expand upon. Or is this just standard practice?
I also notice shorthand if statements that have no brackets as well. Also standard practice?
I want to learn good habits early on, so any advice on this matter would be greatly appreciated.
There are several ways to declare functions and there are use cases and pros and cons to each. As a result, there is no "preferred" way. Use the appropriate syntax for your situation.
Below is a summary of the different ways to set up functions with a brief explanation of each. Click on the heading link to be directed to more in-depth resources on that type:
Function Declaration:
function foo(){
}
With a function declaration, the entire function is hoisted (regardless of it's actual location in the code) to the top of the enclosing scope. This makes it possible to invoke the function prior to its declaration point.
Function Expression:
var foo = function(){
}
Function expressions are just variable declarations that assign a function (as data) to the variable. As with function declarations, there is hoisting here too, but only the variable (foo in this example) declaration gets hoisted, not the assignment, so in this case you could not invoke the function prior to its declaration.
Arrow Functions:
const groceries = (groceryItem) => ' - ' + groceryItem;
This is simply a short hand syntax instead of using a function expression. However, there is a difference with an arrow function. With Arrow Functions, the object that this binds to is not affected within the function, while it is affected in a non-arrow function.
Immediately Invoked Function Expression:
(function(){
})();
An Immediately Invoked Function Expression (IIFE) is an anonymous function (a function with no name) that is turned into an expression by wrapping it with parenthesis and then immediately invoked with another set of parenthesis. This syntax is very common in JavaScript and is used to create a scope that doesn't conflict with other scopes.
NOTE:
Functions are the work horses of JavaScript, depending on how you set them up and invoke them, they do many different things:
They can be units of directly invocable code.
They can be the value of a variable or property.
They can be constructor functions that are used to instantiate Object
instances.
They can be raw data that is passed around via arguments.
Yes, I think this is considered acceptable, since arrow functions were specifically designed to allow it. One of the features of arrow functions is that they allow very simple functions to be written as one-liners like this. When you can calculate the return value as a single expression, you don't need to write the body with braces around it or the return statement explicitly. This makes traditional functions needlessly verbose, with more boilerplate than the actual code of the function. The traditional alternative would look like:
const groceries = function(groceryItem) {
return ' - ' + groceryItem;
}
This isn't so bad when defining a named function, but when you're using an anonymous function as a callback, all that verbosity may obscure the intent. Compare:
newarray = oldarray.map(function(x) {
return x * x;
}
with:
newarray = oldarray.map(x => x * x);
Arrow functions are a recent addition to the language, so I think we can assume that the design was given significant consideration. If the Javascript community didn't feel that shorthand functions like this were a good idea, they wouldn't have been allowed in the first place.
The function you wrote is what is commonly known as a "arrow function". They can prove very useful when you get to a somehow more advanced level in JavaScript and there is absolutely nothing wrong with them. On the contrary. Very commonly used with "higher order functions" for arrays, to give an example.
Recently I have seen these functions in tutorials. Are they equivalent?
(_ => console.log(1))();
(() => console.log(1))();
The two functions do exactly the same thing. The only difference is that the top function takes one parameter, _, while the other takes zero. This doesn't matter in this example, since you don't use the _ variable.
If however, you are using _ as a variable name, and you use it in the function, you will run into problems. Example:
(_ => console.log(_))();
is not the same thing as
(() => console.log(_))();
In the first line, the function prints the value of the parameter _, which, in this case is undefined, since no value is passed to it. In the second line, the function prints the value of the global variable _. This can become a problem if you use a library like underscore.js, where the variable _ is used.
A "fat arrow" (=>) function can be declared with a single identifier parameter name, or with a parenthesized lists of zero or more parameters. Your first example
(_ => console.log(1))();
is the first case, with the parameter name being "_". The second example is a parameter list with no parameters:
(() => console.log(1))();
Neither function makes use of its parameters, and both invocations pass no parameters. That is, both function calls have no actual arguments; the statements both end with (). Whether the two are "equivalent" or not depends on your definition of "equivalent". In both cases, exactly the same thing will happen. However, the anonymous fat-arrow functions are not exactly the same.
No, they are not equivalent. The first is an anonymous fat arrow function with 1 parameter, the second is an anonymous fat arrow function with 0 parameters. The first, thus, relies on the fact that passing too few arguments to a function is not an error in ECMAScript.
The underscore _ is sometimes used to indicate a parameter that is required to fulfill a certain contract but is actually ignored. However, in this case, that is a misuse of this convention since the parameter isn't required: the function is called without arguments, so there is no need to declare a parameter.
I am using a cross-compiler (Babel, soon to be TypeScript) for ES6 and it currently does not support proper .call behavior for functions made with the => syntax; when I call them with .call, their this value is still the one they inherited from the parent scope when I first made them, instead of being the first argument I passed in with .call.
Is this their intentional behavior, as per the ES6 standards (which would be very disappointing)? Or is this just a limitation of the cross-compiler?
This is what the spec says:
An ArrowFunction does not define local bindings for arguments, super,
this, or new.target. Any reference to arguments, super, this, or
new.target within an ArrowFunction must resolve to a binding in a
lexically enclosing environment.
I.e. it's fixed to the context in where it was defined. You can't dynamically change it. Specifically on Function.prototype.call it says:
If func is an arrow function or a bound function then the thisArg will
be ignored by the function [[Call]] in step 5.
If you use a function like methodical bellow it will create a method where this is passed in as the first argument of the callback. That way you have all the benefits of the fat arrow syntax (implicit return, this not being lost on subsequent function calls) but still being able to use it as a method. Of course there is also the short-hand method syntax which is basically creates a traditional es5 style function (slightly different as it can't be called with new).
const methodical = func => function(...args) {
return func(this, ...args)
}
const add = methodical(
(instance, name, value) => (instance[name] = value, instance)
)
const a = {
add
}
a.add('first', 1.23).add('second', 2.74)
add.call(a,'third', 3.11)
console.log(JSON.stringify(a, null, 2))
using es2015 shorthand methods instead
const b = {
add(name,value) {
this[name] = value
return this
}
}
b.add('first',1).add('second',2)
console.log(JSON.stringify(b))
I've seen it done differently in code out there, but is there any benefit or reason to doing a (blank params) .call / .apply over a regular () function execution.
This of course is an over-simplified example
var func = function () { /* do whatever */ };
func.call();
func.apply();
VERSUS just the simple parenthesis.
func();
Haven't seen any information on this anywhere, I know why call/apply are used when params are passed.
When you call a method with func();, this variable inside the method points to window object.
Where as when you use call(...)/apply(...) the first parameter passed to the method call becomes this inside the method. If you are not passing any arguments/pass null or undefined then this will become global object in non strict mode.
Yes, there is an important difference in some cases. For example, dealing with callbacks. Let's assume you have a class with constructor that accepts callback parameter and stores it under this.callback. Later, when this callback is invoked via this.callback(), suddenly the foreign code gets the reference to your object via this. It is not always desirable, and it is better/safer to use this.callback.call() in such case.
That way, the foreign code will get undefined as this and won't try to modify your object by accident. And properly written callback won't be affected by this usage of call() anyways, since they would supply the callback defined as an arrow function or as bound function (via .bind()). In both such cases, the callback will have its own, proper this, unaffected by call(), since arrow and bound functions just ignore the value, set by apply()/call().