Functions and parenthesis in Javascript - javascript

I don't understand how all those f() function work, can someone explain why it prints two '1', I know it prints '1' for every '()' after f(f), but I don't know why.
function f(y) {
let x = y;
var i = 0;
return () => {
console.log(++i);
return x(y);
};
}
f(f)()();
And why does the 'i' doesn't increase?
Thank you.

function f(y) {
let x = y;
var i = 0;
return () => {
console.log(++i);
return x(y);
};
}
f(f)()();
is equivalent to
function f() {
var i = 0;
return () => {
console.log(++i);
return f();
};
}
const t1 = f();
const t2 = t1();
t2();
is equivalent to
function f() {
var i = 0;
return () => {
console.log(++i);
};
}
const t1 = f();
t1();
const t2 = f();
t2();
If you did call each of t1 or t2 multiple times instead of just once, you'd increment the i from the respective closure some more. But if you instead just chain them, they call f again and initialise a new var i = 0 for a different closure.

First, the f(y) function essentially calling y onto itself. Executing f(y) would return a new function, which when executed, would execute x(y) and return the results.
To reduce the confusion, it's just calling f(f) for each f() you executed in this example, as x === y and y === f. The important part of why i never seems to increase, is that every execution creates a new i.
What happens in behind are:
f(f)()();
// is same as
const f1 = f(f);
const f2 = f1();
const f3 = f2();
// f(f) would execute first, and returns () => {
// console.log(++i);
// return x(y); // which is same as returning f(f) in this example
// }
Notice that executing f(f) returns x(y) which x(y) seems to be equal to f(f). Seems as it is similar in code, but different instance. Another point is that i was never carried to this new function, nor are shared to the other instances. Each f(f) creates a new i, never passed to the next function.

Let's name the function at line 4 , function A.
return result of function f() is function A.(at line 4 you define a function, you don't call it.)
the body of A is gonna be this and since you use those variables in an inner function, they are not gonna be exposed(i = 0, x = y = f ):
function A(){
console.log(++i);
return x(y);
so what you have now is: A()().
First parenthesis: A() prints a '1' and returns result of f(f) which is function A.(the first i is exposed and a new i is created)
Second parenthesis : A is executed like I said and return another A, since there are no any parenthesis left, there is no more call.

You declare in f always a new i.
Instead, you could store the count into a property of the function itself.
function f(y) {
let x = y;
f.i = f.i || 0;
return () => {
console.log(++f.i);
return x(y);
};
}
f(f)()()();

Related

JavaScript Callback: Reference Error on line 206: ouput2 is not defined

I'm trying to create a function that accepts two callbacks and a value that will return a boolean indicating if the passing the value into the first function, and then passing the resulting output into the second function, yields the same output as the same operation in reverse (passing the value into the second function and then passing the output into the first function).
I get the following error and I believe it is probably due to scoping but not sure how to resolve it: Reference Error on line 206: ouput2 is not defined
function commutative(func1, func2, value) {
//check to see if invoking cb1 on value then passing output to cb2 as cb2 => cb1
function func1() {
let output1 = func1(value);
return output1;
}
function func2() {
let output2 = func2(output1);
return output2;
}
function reverseOrder() {
let output3 = func2(value);
let output4 = func1(output3);
}
//return boolean
if (ouput2 === output4) {
return true;
} else {
return false;
}
}
// Test cases:
const multBy3 = n => n * 3;
const divBy4 = n => n / 4;
const subtract5 = n => n - 5;
console.log(commutative(multBy3, divBy4, 11)); // should log: true
console.log(commutative(multBy3, subtract5, 10)); // should log: false
console.log(commutative(divBy4, subtract5, 48)); // should log: false
You are never calling your inner functions, and output1, output2, etc. are defined locally to those inner functions, not accessible in the scope of commutative. Also, you are overwriting the func1 and func2 parameters. Try this:
function commutative(func1, func2, value) {
return func2(func1(value)) === func1(func2(value));
}
// Test cases:
const multBy3 = n => n * 3;
const divBy4 = n => n / 4;
const subtract5 = n => n - 5;
console.log(commutative(multBy3, divBy4, 11)); // should log: true
console.log(commutative(multBy3, subtract5, 10)); // should log: false
console.log(commutative(divBy4, subtract5, 48)); // should log: false

Why multiple functions inside an IIFE execute the last function?

I have actually no idea how the output of this code is a number. Someone kindly help understanding with what logic is JS running in this example?
<script>
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)();
console.log(typeof f);
</script>
You're using the comma operator. You're basically executing g here
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)()
is similar to:
var temp = function g(){ return 2; }
f = temp() // returns 2
Because of the comma operator.
x = a, b;
This evaluates a, then it evaluates b, and the result of b is used. That is, a is only evaluated for its side effects, otherwise its result is discarded.
That means that
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)();
is a fancy way of writing
var f = (function g(){ return 2; })();
which is a fancy way of writing
var f = 2;
and 2 is a number.
Here f is not a function.
Instead contains the value returned by g function.
f currently holds to the value returned in IIFE
var f = (
function f(){ return "1"; },
function g(){ return 2; }
)();
console.log(f);
</script>
So, right, the comma operator. But more important is the change of the context of the functions. They are not anymore accessable from the global scope.
Some expanations may be in this answer of Does the comma operator influence the execution context in Javascript?:
var f = (
function f() { return "1"; },
function g() { return 2; }
)();
console.log(f);
console.log(typeof f);
console.log(g()); // throws error: 'g' is not defined

JavaScript Closure - trying to understand following code

Coming from Java background trying to make sense out of the following code.
From:
https://medium.freecodecamp.com/lets-learn-javascript-closures-66feb44f6a44#.cbk6c4e9g
For function bar(c), which line passes argument c into bar(c) as I don't see it here.
Thanks.
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5); // Closure
/*
The function below executes the function bar which was returned
when we executed the function foo in the line above. The function bar
invokes boop, at which point bar gets suspended and boop gets push
onto the top of the call stack (see the screenshot below)
*/
moar(15);
When your first statement of function call var moar = foo(5) is executed
moar variable will be function bar(c){var d=30;return boop(x+a+b+c+d);
check the snippet for understanding
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
return bar;
}
var moor=foo(10);
console.log(moor);
2.After this statement moar(15),your are actually passing 15 to the bar method
It will execute bar method with c as 15. Now this function would return boop(80) which would just be -80
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5)
console.log(moar(15));
Hope it helps
moar(15) passes 15 into bar which gets copied into parameter c.
The // Closure comment is misleading because it is more useful to think of the closure being configured at the point of declaration of a function.
The reality is that the pointer to the outer lexical environment is configured when a function object is instantiated, and then this pointer is then copied to the execution context associated with any invocations of said function object.

Object function scope

factory(n) returns objects with functions.
func1 function definition creates its own scope, and x inside this function references x = n + ''.
But func2 is a reference and the scope is wrong.
Is there a way to return an object from create so its functions were references (not separate definitions)?
Actually, I'm fine with func1 approach while function definition footprint is small. If it is a complex function it would be better not to clone this function into every object comming from factory(n). inner_func may not use this, it is simple function. Also I want to avoid new and this.
var factory = (function(){
var x = '!';
return function create(n){
var x = n + '';
return {
func1: function(y){return inner_func(x, y); },
/* vs */
func2: inner_func_api
}
}
function inner_func_api(y){ return inner_func(x, y); }
function inner_func(a, b){ return a + b; }
}());
var f1 = factory(2);
var f2 = factory(3);
var f1_func1 = f1.func1(4);
var f2_func1 = f2.func1(5);
var f1_func2 = f1.func2(4);
var f2_func2 = f2.func2(5);
console.log(f1_func1, f2_func1); //24 35
console.log(f1_func2, f2_func2); //!4 !5
You could define that function separately from the object initializer on the return statement:
var factory = (function(){
var x = '!';
return function create(n){
var x = n + '';
function func1(y) {
return inner_func(x, y);
}
return {
func1: func1,
/* vs */
func2: inner_func_api
}
}
function inner_func_api(y){ return inner_func(x, y); }
function inner_func(a, b){ return a + b; }
}());
However, it makes no practical difference, and it doesn't matter how big or complicated that function is. Function instances do take up space, but the code for the function is constant (immutable) and doesn't need to be part of every Function object created from the same piece of source code.

How to call a function with a function as parameter?

As a beginner in Javascript, I am trying to call a function whose parameter is a function.But I get this error.
function execute(f) {
f();
}
var m = function(x) { return x * x };
m(8) #=> returns 64
execute(m(8)) #=> Uncaught TypeError: number is not a function
I guess function execute is executing m(8) before exercising its body, therefore the call becomes execute(64). If so, how do I go about passing a function with a parameter?
You'll have to pass them as separate parameters and use call or apply.
For example :
function execute(f, args) {
return f.apply(null, args);
}
var m = function(x) { return x * x };
m(8)
execute(m, [8])
Now, let's suppose you want to have functions taking any number of arguments, and you don't want to bother with making an array. Then it's a little more fun :
function execute() {
return arguments[0].apply(null, [].slice.call(arguments, 1));
}
var m = function(x,y) { return x * y };
console.log(m(8, 4))
console.log(execute(m, 8, 4))
You can use bind to partially apply 8 to m:
function execute(f) {
f();
}
var m = function(x) { return x * x };
execute(m.bind(null, 8))

Categories