I'm doing a tutorial on lexical scope handling by Typescript and I've come across the use of a function which I have never seen before. Which looks like an empty function in a forEach statement. In typescript it looks like this:
fns.forEach(fn=>fn());
In javascript it looks like:
fns.forEach(function (fn) { return fn(); });
I've never seen a function used like this. Can someone explain how this works? To be specific, what is fn=>fn() actually executing. In reference to the code below, is it executing the fns.push or for loop? If it is the For Loop there's no reference to this so how does it know?
Below is the full code:
TypeScript:
var fns = [];
for(var i=0;i<5;i+=1){
fns.push(function(){
console.log(i);
})
}
fns.forEach(fn=>fn());
JavaScript
var fns = [];
for (var i = 0; i < 5; i += 1) {
fns.push(function () {
console.log(i);
});
}
fns.forEach(function (fn) { return fn(); });
Check out this example:
var method = a => a+1;
method is a var that holds a reference to a function.
a is the input param.
a+1 is the methods body and return type.
Typescript will transpile this into:
var method = function (a) { return a + 1; };
Check out the typescript playground example and you will understand the concept pretty fast.
In your example fns is an array of functions.
doing fns.forEach(fn=>fn()); means execute each method in the fns array.
fn => fn() is a function definition, in C# they are called Lambda expressions and it is just syntactic sugar for the same function (fn) { return fn(); }.
fn is the input parameter, and => defines it as a function and the fn() is the return value.
Another example is
var add = (a,b) => a + b;
is the same as
function add(a, b) {
return a + b;
}
It is looping through an array of functions, because functions can be stored inside variables just like strings, integers etc. So you're looping through an array of functions and executing them like this: return fn();
Related
I have the following code that includes Spread Syntax in JS
const opposite = function (f) { return (function (...args) { return !f(...args) }) };
can it be converted without using Spread Syntax? It seems that if I do use this, some of the js minification tools fail to parse these lines of codes.
You can by using the arguments object in combination with Function.prototype.apply():
The arguments object exist inside every function call and it represents the arguments to the function. Using this we can capture any and all arguments passed to the function.
The apply method on the other hand allow you to call a function by passing an array to represent the arguments.
Combining both we can do this:
const opposite = function (f) {
return (function () {
return !f.apply(null, arguments)
})
};
would be to use the apply method, like this:
const opposite = function (f) {
return function () {
return !f.apply(this, arguments);
}
};
Another way to achieve the same result would be to use the call method and pass the arguments object to the function, like this:
const opposite = function (f) {
return function () {
return !f.call(this, ...arguments);
}
};
Both of these methods allow you to pass an arbitrary number of arguments to the function without using the spread syntax.
I am learning javascript and have seen anonymous functions written like this without any explanation:
const sum = (function() {
return function sum(x,y,z){
return (x+y+z);
};
})();
console.log(sum(1,2,3)); //6
The way I read it is: declare a function anonymously and assign it to the const sum. Call sum() with the parameters and console.log() the results.
This is very confusing to me as I don't understand why it is written the way it is. Some questions are:
How is sum accepting parameters when the outermost function has no parameters specified?
Why are we not specifying the parameters on the outermost function?? Why is it returning itself and which 'sum' gets called when?
Apologies if it is too dumb or obvious. I have struggled a lot and have finally decided to ask here.
First of all this function is not only anonymous. it's an iife (immediately invoking function) and it's returning sum function. So const variable sum is actually sum function that is returned by iife function.
console.log(sum(1,2,3));
So, in the above line sum is referring to the function sum returned by iife function not the iife function itself
For more understanding about iife check - https://developer.mozilla.org/en-US/docs/Glossary/IIFE
For better understanding, we can expand it to:
const _sum2 = function() { // anonymous function
return function sum(x,y,z){
return (x+y+z);
};
}
const sum = _sum2(); // value of _sum2 returns
// it is the same as
const sum = function sum(x,y,z){
return (x+y+z);
}
console.log(sum(1,2,3));
Test it yourself:
const sum = (function() {
return function sum(x,y,z){
return (x+y+z);
};
})();
console.log('const sum = ' + sum.toString());
such syntax is used to protect intermediate valiables and functions. In your case there are no such variables, but:
const sum = (function() {
const n = 10;
function protected() {
return n;
}
return function sum(x,y,z){
return protected() * (x+y+z);
};
})();
console.log(sum(1,2,3)); // evaluates to 60
function protected and variable n are sealed and not exposed to your global environment.
For beginners, the following code is horribly loaded with confusing unnecessary misinformation:
const sum = (function() {
return function sum(x,y,z){
return (x+y+z);
};
})();
The outer anonymous function is NOT necessary since there is no inner variables or functions to protect -- so why use it at all?? It only serves to confuse!!
Why use "sum" to name the inner returned anonymous function? It has nothing to do with the const sum, and only causes more confusion here!!
All the above code is completely unnecessary, redundant, and confusing when considering the following is the same:
const sum = (x, y, z) => x + y + z;
console.log(sum(1,2,3));
I'm new to functional programming and I'm trying to learn it in javascript. I found some examples and wrote my own snippet, but I don't understand WHY it works. There is a function called whatTheHeckIsThis. Can someone tell me what it is doing or what its purpose is? Note that when running this code, the output is true.
function boolFlipper(someFn){
return function whatTheHeckIsThis(x,y){
return !someFn(x,y);
};
}
var checkStrings = function(x, y){
return x === y;
}
var flipperTester = boolFlipper(checkStrings);
var str1 = "this string";
var str2 = "that string";
console.log(flipperTester(str1, str2));
My confusion is why can't I just do this instead:
function boolFlipper(someFn){
return !someFn(x,y);
}
a reference to whatTheHeckIsthis() will be returned and stored into flipperTester
After this, flipperTester can be used like a function.
You can use this language feature to abstract some code.
Simple example:
function addTen(x) { return x + 10 }
function multiplyByTen(x) { return x * 10 }
...
var doMath
// somewhere a user selected something
if (userInputSaysAdd) doMath = addTen
if (userInputSaysMultiply) doMath = multiplyByTen
// this will be the choosen function
doMath(someValue)
Your second version doesn't work for 2 reasons:
The purpose of boolFlipper is to return a new function, which you can assign to another variable and later call.
Your function doesn't have x and y parameters.
To solve #2 you could write:
function boolFlipper(someFn, x, y) {
return !someFn(x, y);
}
You would then have to call it like:
console.log(boolFlipper(checkStrings, str1, str2));
But you still couldn't do:
flipperTester = boolFlipper(checkStrings);
The original snippet returns a closure, which is bound in the environment where someFn is equal to the function passed as an argument to bookFlipper(). You can then assign this function to a variable, and call it with new arguments, that are assigned to x and y, and then the the function saved in someFn() is called, the return value is negated with !, and this is returned.
For more information about closures, see How do JavaScript closures work?
In JavaScript functions are objects, so you can return them. When you return a function you are getting a function object, so you can call it as any other function. For example:
function myFun() {
return function() {
console.log("test");
};
}
var functionInside = myFun();
/* This is like doing:
var functionInside = function() {
console.log("test");
};
*/
functionInside(); // This will execute the function.
Example with your code:
This variable:
var flipperTester = boolFlipper(checkStrings);
contains a function like this:
var flipperTester = function (x,y) {
return !someFn(x,y);
}
And this is something similar to
function flipperTester(x,y) {
return !someFn(x,y);
}
So when you do:
flipperTester(str1, str2)
You are executing that function. The variable "someFn" inside there is the function "checkStrings", because you passed it when you initialize flipperTester variable.
boolFlipper is, for our purposes here, a function decorator: it takes a function and modifies it to do something else. A more instructive example might be a logging function:
var alsoLogs = f => (...args) => {
var result = f(...args);
console.log(result);
return result;
};
// now we have a function that adds 2 numbers:
var add = function add(a, b) { return a + b; };
// and we want to also log the result
var addAndLog = alsoLogs(add); // addAndLog is a function, would be the whatTheHeckIsThis from your example
addAndLog(2, 3); // logs 5 to the console
If you don't understand all the ES6 syntax that's ok, just understand that alsoLogs take a function f and returns a function that does the exact same thing as f but also logs the result to the console.
Since we as programmers are lazy, we don't want to have to write functions to glue together other functions every time we want to do this, so we write a function to do it for us, compose.
So now we can just say something like:
var addAndLog = R.compose(console.log, add);
addAndLog(2, 3); // logs 5 to the console
I have the code below:
//anonymous function expression
var a = function() {
return 3;
}
//named function expression
var a = function bar() {
return 3;
}
So, what is the different between them ? (technical, usage)
The main differences are
You can inspect the function name (for example stack traces are more readable)
The function can be recursive
Note that a function like
var fibo = function(n) {
return n<2 ? 1 : fibo(n-1) + fibo(n-2);
};
is not really recursive as its body will call whatever fibo is bound to at the moment of the call (so it will not call itself if fibo is later assigned to something else). The version
var f = function fibo(n) {
return n<2 ? 1 : fibo(n-1) + fibo(n-2);
};
is instead really recursive and will keep calling itself no matter what f is later bound to.
In the below, I'm confused by the syntax
(function (h,j) { })
What does it mean in javascript to have a function sit inside ()'s like that?
function myfunc(c, b) {
try {
(function (h, j) {
//do a bunch of stuff
})
} catch (e) {
myerror(e)
}
};
By itself, such a function declaration is useless. This kind of declaration is only useful if you actually invoke the function, which is done like this:
(function (h, j) { ... } (x, y));
This is usually done to hide variables, since JavaScript only has function scope (no block scope).
Edit:
Some examples - hopefully these don't confuse things...
As mentioned in a comment, this technique is useful for keeping variables out of the global scope. For example, some initialisation script might do the following:
(function () {
var x = 42;
var y = 'foo';
function doInitialisation(a, b) {
// ...
}
doInitialisation(x, y);
}());
None of x, y or doInitialisation are visible after the function completes.
Another use-case is for avoiding closures in loops. E.g. the following causes a well-known problem:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = function () {
alert(i);
};
}
In the above example, every onclick handler shares the same value of i. Function scope can avoid this:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = (function (x) {
return function() {
alert(x);
}
}(i));
}
() is a grouping operator, and it returns the result of evaluating the expression inside it.
So while
> function(x,y) {}
SyntaxError: Unexpected token (
by itself is a SyntaxError, but by surrounding it in parentheses, the expression inside the parentheses is evaluated and returned.
> (function(x,y) {})
function (x,y) {}
Function expressions and declarations do not yield any value, so we get undefined as a result.
Function Declaration
> function a(x,y) {}
undefined
Function Declaration (with grouping operator)
(function a(x,y) {})
function a(x,y) {}
Function Expression
> var x = function(x,y) {}
undefined
Function Expression (with grouping operator)
> var x;
> (x = function(x,y) {})
function (x,y) {}
However, the usage in your example seems to be useless. It does nothing.
That syntax is what is known as an Anonymous Function. Most often, you will see them used as callbacks for various other function calls (for example, in jQuery).
It's a kind of inline function, so you can take the advantages of covariance. By this I mean,inside
(function (h, j) {
//do a bunch of stuff
})
You can access the variables of the containing function , here it's function myfunc(c, b) {}