Preferred usage of variadic functions in js - javascript

Here I have two functions:
function myFunc() {
for(let key in arguments){
console.log(arguments[key])
}
}
function myFunc2(...args) {
args.forEach(arg=>console.log(arg));
}
Which of the above is the preferred usage of variadic functions in javascript and why?
Are there any advantages or disadvantages to one over another?
Thanks in advance.

Related

JavaScript making something unnecessarily complicated

I see code blocks all the time where people make it unnecessarily complicated. What is the reason for this?
Example:
const greet = function (greeting) {
return function (name) {
console.log(`${greeting} ${name}`)
}
}
const greeterHey = greet('Hey');
greeterHey('test')
instead of something like this
const greet = function (greeting, name) {
console.log(`${greeting} ${name}`)
}
const greeterHey = greet('Hey', 'test');
What is it all about? Does it have anything to do with the fact that when you edit the code block later, it's easier?
It is probably an example of function currying or higher-order function, a technique in Functional Programming Paradigm. Curryinng is IMO quite probably the single most important thing in Functional programming with Haskell for example.
The example is probably just for easy demonstration, however, the technique is quite powerful if used in correct situations.
By currying multiple-parameter function into chains of one-argument functions, you can create what I called "Niche function"
const greet = function (greeting) {
return function (name) {
console.log(`${greeting}, ${name}`)
}
}
// greetWithHello kinda retains the same logic as `greet`, but now has become more "niche"
// because you can only greet with "Hello"
const greetWithHello = greet("Hello"); //greetWithHello is a FUNCTION
greetWithHello("Ben") // "Hello, Ben"
greetWitHello("Bob") // "Hello, Bob"
const greetWithBadaboom = greet("Badaboom")
As you can imagine, instead of keep writing greet("Hello", "Ben") and greet("Hello", "Bob"), you now have a more reusable greetWithHello function.
Compared this with the un-curried version
const greet2(phrase, name) {
console.log(`${phrase}, ${name}`)
}
const greetWithHello2 = (name) => {
return greet2("Hello", name)
}
const greetWithBadaboom2 = (name) => {
return greet2("Badaboom", name)
}
As you can see, much less composable and readable than the curried version, and this is just for 2 parameters. This is why functional programming patterns can be very useful when working with functions
I only know this from college and never actually used it myself, but I guess libraries with higher-order-functions may utilize this
This is related to something called "closures" which, in short, allows to create functions that return functions, and those retain the values you provided, variables or constants alike.
In other languages, variables or constants created inside the scope/block of a function only live during the execution of such function. In JavaScript, when using this syntax, a "lexical environment" is created, and the returned function can also access values out of its own scope/environment.
As stated in the other answers, it's a very useful characteristic when used correctly in higher-order functions.
There are some examples and a more clear explanation in the MDN page about closures:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

JavaScript arrow function assignment

I tried googling that , but i can not discuss to google, sometimes in the courses i saw the instructor assign an arrow function to a variable like that.
const s = ( ) => { }
what are the cases when I need that syntax and not using
function s( ) { }
My BASIC Question --> when to use
const s = ( ) => { }
versus
function s( ) => { }
.. why the assignment ... thats my main Question (when and why i assign ?) why not use the arrow function without assigning it to a variable ??
Your examples are showing 2 ways to declare a function.
This is an example of a function declaration.
function s() {
// some code
}
This is another way to define a function, called function expression.
const s = function() {
// some code
}
This is an arrow function. With the exception of the way this is treated between the arrow function and the other two, they are pretty much 3 ways to write the same function.
const s = () => {
// some code
}
As stated in the response below, function declaration and function expression are ES5 features and the arrow function is an ES6 feature.
Your examples do different things: the first declares a function s, the second one calls s().
For the sake of clarity...
// ES5
var multiplyES5 = function(x, y) {
return x * y;
};
// ES6
const multiplyES6 = (x, y) => {
return x * y;
};
Where Arrow Functions Improve Your Code ( where you should use them ) -
One of the primary use cases for traditional lambda functions, and now for arrow functions in JavaScript, is for functions that get applied over and over again to items in a list.
For example, if you have an array of values that you want to transform using a map, an arrow function is ideal:
const words = ['hello', 'WORLD', 'Whatever'];
const downcasedWords = words.map(word => word.toLowerCase());
An extremely common example of this is to pull out a particular value of an object:
const names = objects.map(object => object.name);
Similarly, when replacing old-style for loops with modern iterator-style loops using forEach, the fact that arrow functions keep this from the parent makes them extremely intuitive.
this.examples.forEach(example => {
this.runExample(example);
});
Promises and Promise Chains - Another place arrow functions make for cleaner and more intuitive code is in managing asynchronous code.
Promises make it far easier to manage async code (and even if you're excited to use async/await, you should still understand promises which is what async/await is built on top of!)
However, while using promises still requires defining functions that run after your asynchronous code or call completes.
This is an ideal location for an arrow function, especially if your resulting function is stateful, referencing something in your object. Example:
this.doSomethingAsync().then((result) => {
this.storeResult(result);
});
Object Transformations -
Another common and extremely powerful use for arrow functions is to encapsulate object transformations.
For example, in Vue.js there is a common pattern for including pieces of a Vuex store directly into a Vue component using mapState.
This involves defining a set of "mappers" that will transform from the original complete state object to pull out exactly what is necessary for the component in question.
These sorts of simple transformations are an ideal and beautiful place to utilize arrow functions. Example:
export default {
computed: {
...mapState({
results: state => state.results,
users: state => state.users,
});
}
}
Where You Should Not Use Arrow Functions -
There are a number of situations in which arrow functions are not a good idea. Places where they will not only help, but cause you trouble.
The first is in methods on an object. This is an example where function context and this are exactly what you want.
There was a trend for a little while to use a combination of the Class Properties syntax and arrow functions as a way to create "auto-binding" methods, e.g. methods that could be used by event handlers but that stayed bound to the class.
This looked something like:
class Counter {
counter = 0;
handleClick = () => {
this.counter++;
}
}
In this way, even if handleClick were called with by an event handler rather than in the context of an instance of Counter, it would still have access to the instance's data.
The downsides of this approach are multiple,
While using this approach does give you an ergonomic-looking shortcut to having a bound function, that function behaves in a number of ways that are not intuitive, inhibiting testing and creating problems if you attempt to subclass/use this object as a prototype.
Instead, use a regular function and if necessary bind it the instance in the constructor:
class Counter {
counter = 0;
handleClick() {
this.counter++;
}
constructor() {
this.handleClick = this.handleClick.bind(this);
}
}
Deep Callchains -
Another place where arrow functions can get you in trouble is when they are going to be used in many different combinations, particularly in deep chains of function calls.
The core reason is the same as with anonymous functions - they give really bad stacktraces.
This isn't too bad if your function only goes one level down, say inside of an iterator, but if you're defining all of your functions as arrow functions and calling back and forth between them, you'll be pretty stuck when you hit a bug and just get error messages like:
{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()
Functions With Dynamic Context -
The last situation where arrow functions can get you in trouble is in places where this is bound dynamically.
If you use arrow functions in these locations, that dynamic binding will not work, and you (or someone else working with your code later) may get very confused as to why things aren't working as expected.
Some key examples of this:
Event handlers are called with this set to the event's currentTarget attribute.
If you're still using jQuery, most jQuery methods set this to the dom element that has been selected.
If you're using Vue.js, methods and computed functions typically set this to be the Vue component.
Certainly you can use arrow functions deliberately to override this behavior, but especially in the cases of jQuery and Vue this will often interfere with normal functioning and leave you baffled why code that looks the same as other code nearby is not working.
this excerpt is taken from here
I assume you mean function s( ) { } in your update.
Notice how that function declaration contains the name s. This implicitly creates a variable s and assigns the function to it. An arrow function definition does not contain a name. So in other to use/call/reference the function elsewhere you have to assign it to a variable explicitly.
why not use the arrow function without assigning it to a variable ??
The only why do this is to put calling parenthesis after the definition, e.g.
(() => console.log('test'))()
This will define and call the function immediately, printing "test" to the console.
But there is not much point in doing that, since the code is equivalent to just writing
console.log('test')
So in JavaScript we write function expressions all the time, so much so that it was decided that there should be a more compact syntax for defining them. It's another way to write a function.
const square = x => {
return x * x;
}
I deliberately have no parens surrounding the x because when there is only one argument, current syntax says we can do away with parens.
The above is actually fully functional, you can run square(4); on it and get 16.
Imagine you have nested callbacks written like this:
const square = function(x){
return x * x;
}
Seeing the keyword function all over the place, could drive you batty after awhile.
Arrow functions are cleaner and leaner, but arrow functions is not just syntactic sugar, there is another difference and that is regarding the keyword, this.
If you do not have extensive knowledge of the keyword this, I highly recommend you start to source some solid information out there on the topic, at least as it relates to arrow functions. That research should uncover in what cases you would need to use an arrow function.
As far as why assign it a variable, you have to look at the evolution of the arrow function as outlined by mph85. You go from function declaration:
function isEven(num) {
return num % 2 === 0;
}
to an anonymous function declaration assigned as a variable named isEven:
const isEven = function(num) {
return num % 2 === 0;
}
to the anonymous function declaration assigned to a variable called isEven evolving to an arrow function expression assigned to said variable.
const isEven = (num) => {
return num % 2 === 0;
}
And we can up the ante and make this more concise with an implicit return where we can drop the parens, curly braces and return keyword like so:
const isEven = num => num % 2 === 0;
I think it's important to observe how this evolves so whenever you see the last version above, it will not throw you off.

Javascript memory implication of nested arrow functions

Consider:
function f1() {
function n11() { .. lots of code .. };
const n12 = () => { .. lots of code .. };
return n11()+n12()+5;
}
const f2 = () => {
function n21() { .. lots of code .. };
const n22 = () => { .. lots of code .. };
return n21()+n22()+5;
}
I am trying to understand the memory implications of calling f1 and f2.
Regarding n11, this answer says:
For some very small and normally inconsequential value of "wasted".
JavaScript engines are very efficient these days and can perform a
wide variety of tricks/optimizations. For instance, only the
function-object (but not the actual function code!) needs to be
"duplicated" internally. There is no "wasting" problem without an
actual test-case that shows otherwise. This idiom (of nested and
anonymous functions) is very common in JavaScript and very
well-optimized for.
However I want to know if this also apply to arrow functions (ie n12, n21 and n22) .. will the overhead only be a function-object as above or will the entire nested function code be duplicated every time f1/f2 are called ?
thx!
There's absolutely no reason why an implementaton would need to do anything different for arrow functions than traditional functions with regard to the sharing of code between different closures of the same function. The only difference between arrow functions and traditional functions is that arrow functions save the this value. This can be done using the same mechanism as is already provided for the Function.prototype.bind() method. An arrow function is mostly just syntactic sugar.
func = () => { body };
is roughly equivalent to:
func = function() { body }.bind(this);
(This is a slight simplification, since arrow functions also don't get an arguments object, but that shouldn't affect what you're asking.)

JS - function declared inside a function

Is it ok regarding performance and efficiency to declare a function inside a function that is called on each AnimationFrame?
Is A) as ok as B) ?
A)
function update() {
function do () { ...}
}
B)
function update() {
do();
}
function do () { ...}
No, it's not a good idea because you're making it redeclare the same function over and over.
A better pattern would be:
(function() { // this is your closure
var genericVariableOne = 123,
genericVariableTwo = 456;
function genericFunctionOne() {...}
// now do stuff here
})();
This way you are only declaring functions once within the closure. For variables, declaring them outside may or may not be a good idea depending on how they are used.
Yes - it is ok to declare functions inside functions and in fact desirable in many situations. They are called closures. All major JavaScript APIs depend on this concept heavily from jQuery, to AngularJS to Dojo. Older versions of MSIE discouraged it's use but all modern browsers use JavaScript engines that are very efficient and can give you good performance with closures.

Why do javascript libraries like jQuery generally prefer anonymous functions over named ones?

There are two common ways to declare a javascript function
Way 1: Named Function
function add(a, b)
{
return a+b;
}
To call the above function we use add(3,4);
Way 2: Anonymous function
var add = function(a, b)
{
return a + b;
}
To call this function we again use add(3,4);
Both produce the same result. I always go with way 1 as I learned javascript this way. But most of the new javascript libraries like jQuery seem to use way 2.
Why is way 2 preferred over way 1 in most of the javascript libraries? As per my understanding both produce the same behaviour. The only difference is in way 1, the function is available to code that runs above, where the function is declared, which is not true in Way 2. Is this the only reason new javascript libraries uses the the way 2, so that they can ensure their libraries are included first and then call their function?
Anonymous functions are used to comfortably define objects. The reason libraries often drop the named declaration and only use anonymous (even when its not specifically needed) is to improve code readability, so you dont have two ways to declare one thing in your code.
var x = function() {
//constructor
}
x.y = function() {
//first method
}

Categories