newbie in javascript closure, and the closure test's result is unexpect - javascript

newbie in javascript closure
i follow a example from internet, and try to change some of it
i think it should give me 16,17,18,19
but the result was unexpect
here is my code.
i do not know why i first call bar2(10),it alert 17, does it should give me 18?
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2);
bar(10);//alert16
bar(10);//alert17
var bar2 = foo(3);
bar2(10);//alert17
bar2(10);//alert18

Because tmp is a variable local to the function you return from foo -- that means when you call foo for the second time, it gets reset to 3. 3 + (3+1) + 10 = 17.

The result 17 is correct.
Each call to foo produces a new function with a new closed-over variable tmp.
Perhaps you thought the second call to foo uses the same tmp as in the first call? It doesn't. That is why you get 17: 3 + 10 + 4.

bar(y) = n = x + y + tmp
bar(10) = 16 = 2 + 10 + 4
bar(10) = 17 = 2 + 10 + 5
bar2(10) = 17 = 3 + 10 + 4
bar2(10) = 18 = 3 + 10 + 5

Related

Can someone explain this code in JavaScript with ++ and brackets?

var m=10;
n=(m++)+(++m)+(m++)+(++m);
Output is
n=48 m=14
How does this answer occur?
Initially m=10. Now when ++ is executed, it will add 1 to the variable. In your code, there are 4 occurences of either ++m or m++, so it will be 14 at the end.
When ++ appears before the variable like ++m, it will add 1 first and use the variable in code. But when it appears after the variable like m++, the variable will be used first and then add 1.
So in n=(m++)+(++m)+(m++)+(++m);,
m++ - m will be used in code as 10 and becomes 11.
++m - m will be incremented by 1 first, so 11+1 =12 and will be used in code.
m++ - m will be used in code as 12 and becomes 13.
++m - m will be incremented by 1 first, so 13+1 =14 and will be used in code.
So, final result will look like this:
n=10+12+12+14
var m = 10;
var m1 = m++;
var m2 = ++m;
var m3 = m++;
var m4 = ++m;
var n = m1 + m2 + m3 + m4;
console.log('n: ' + n);
console.log('m: ' + m);
console.log('(m++): ' + m1 + ', (++m): ' + m2 + ', (m++): ' + m3 + ', (++m): ' + m4);
console.log('---');
var x = 10;
var y = (x++) + (++x) + (x++) + (++x);
console.log('y: ' + y);
console.log('x: ' + x);
m++ this will use previous value of m then increment.
++m this will first increment and then use the incremented value of m.
now,
n=(m++)+(++m)+(m++)+(++m);
-> m++ here the value of m will be first used then increased by 1. so expression will be 10 + (++m) + (m++) + (++m). and for further value of m will be 11.
-> for next it is ++m so it will first increment then use in expression. so previously the value of m was 11, now 11+1 is 12. so expression will look like 10+12 + (m++) + (++m).
-> similarly to first point here also it will first used then increment. so expression will be n=10+12+12+(++m). but after this the value of m is now 13.
-> so here (++m) it will first increment and then add. so previously the value was 13 so 13+1=14. so m is 14 and expression will be n=10+12+12+14.
so the value of n=48 and m=14

Javascript for loop displaying more results than expected

When running the code below, the text inside the document.write runs 8 times and not 7 times as I was expected.
If I understand correctly, increment by 2 should display the positions:
20+2, 22+2, 24+2, 26+2, 28+2, 30+2 and 32+2.
Based on the results I get I assume it also displays the 34+2, which is 36. What I am missing? Thank you.
x = 20;
for (x = 20; x < 35; x += 2) {
document.write("How many times will this loop execute?" + "<br/>");
};
As noted in the comments above, The loop is correct in running 8 times. Since no one stated the reason, it is this: the x+=2 happens at the end of the loop, not at the beginning. So the loop will run for 20, 22, 24, 26, 28, 30, 32, and 34.
You are misunderstanding how the for loop works.
for ([initialization]; [condition]; [final-expression])
final-expression: An expression to be evaluated at the end of each loop iteration. This occurs before the next evaluation of condition. Generally used to update or increment the counter variable.
So your counter gets incremented at the end of the loop and the observed behaviour is correct. The loop gets executed for 20, 22, 24, 26, 28, 30, 32, and 34.
When start loop add +2 to x like below:
x = 20;
for (x = 20+2; x<35; x+=2) {
document.write("How many times will this loop execute?" + "<br/>");
};
fiddle
Script:
x = 20;
count = 1;
for (x = 20; x < 35; x += 2){
document.write("Execution: "+ (count++)+ "<br/>");
};
Output
The loop executes total 8 times.
Execution: 1
Execution: 2
Execution: 3
Execution: 4
Execution: 5
Execution: 6
Execution: 7
Execution: 8
jsfiddle link to checkout.
Yes, is executing 8 times, because is from 20 to 35 in 2 x 2
x = 20;
for (x = 20; x < 35; x += 2) {
document.write("Execute for " + x + " " + "<br/>");
};
/*
OUTPUT:
Execute for 20
Execute for 22
Execute for 24
Execute for 26
Execute for 28
Execute for 30
Execute for 32
Execute for 34
*/
If you want 7 times, you can change to 34
x = 20;
for (x = 20; x < 34; x += 2) {
document.write("Execute for " + x + " " + "<br/>");
};
It will run eight times, x iterating through every even number between 20 and 34 inclusive. You can write it like this if it helps:
var x = 20;
while (x <= 34) {
// do something
x += 2;
}
However, it is important to note that after the loop has run (whether you're using the for or while version), x will equal 36, since it is incremented to that before it finally fails the test; inside the loop, x will never equal 36. In terms of best practice, you should only really use a counter variable like x within the loop; this can be enforced by using the ES6 let keyword (which is block-scoped) like so (the example just prints out a list of the x values as DOM elements):
function appendSpanCounter(i, end) {
let el = document.createElement("span"),
content = i.toString(10);
if (i < end) content += ", ";
(typeof el.textContent === "string") // ternary operator
? el.textContent = content
: el.innerText = content;
(document.body || document.querySelector("body")).appendChild(el);
}
for (let x = 20; x <= 34; x += 2) {
appendSpanCounter(x, 34);
}
// x is now undefined here

Javascript increment operation order of evaluation

I know the what the postfix/prefix increment/decrement operators do. And in javascript, this seems to be no different.
While I can guess the outcome of this line easily:
var foo = 10; console.log(foo, ++foo, foo, foo++, foo);
// output: 10 11 11 11 12
as ++ operators appear within separate expressions.
It gets a bit complicated as these operators appears within the same expression:
var foo = 10; console.log(foo, ++foo + foo++, foo);
// output[1]: 10 22 12
// Nothing unexpected assuming LTR evaluation
var foo = 10; console.log(foo, foo++ + ++foo, foo);
// output[2]: 10 22 12
// What? Ordering is now different but we have the same output.
// Maybe value of foo is evaluated lazily...
var foo = 10; console.log(foo, foo + ++foo, foo);
// output[3]: 10 21 11
// What?! So first 'foo' is evaluated before the increment?
and my question is, how does Javascript (V8 in this case, as I tested these in Chrome) end up evaluating the addition expression in 2nd and 3rd example differently?
Why does foo end up evaluating differently than foo++. Isn't postfix ++ supposed to increment after the expression and just evaluate to foo within expression?
Just look at:
foo++ + ++foo
Mentally rewrite it to:
foo++ →
addition_lhs = foo // addition_lhs == 10
foo += 1 // foo == 11
++foo →
foo += 1 // foo == 12
addition_rhs = foo // addition_rhs == 12
addition_lhs + addition_rhs == 10 + 12 == 22
And foo + ++foo:
foo →
addition_lhs = foo // addition_lhs == 10
++foo →
foo += 1 // foo == 11
addition_rhs = foo // addition_rhs == 11
addition_lhs + addition_rhs == 10 + 11 == 21
So everything is evaluated left to right, including the incrementation.
The crucial rule to understand is that in JavaScript the whole left hand side (LHS) is executed, and the value memorized, before any operation gets done on the right hand side (RHS).
You can either confirm the evaluation order by reading the standard or just place a runtime error in your expression and look what happens:
alert(1) + alert(2) + (function () { throw Error(); })() + alert(3)
Understand that when you use foo++ you're telling to the "compiler": after you push it to the stack, increment it. When you use ++foo you're telling the other way: increment it then push it to the stack.
The ++ operator have preference over the +, since the "compiler" read the expression this way (foo++)+(++foo)
var foo = 10; console.log(foo, ++foo + foo++, foo);
++foo + foo++
11 + 11
The pre increment sets foo to 11 then adds it to foo again which is still 11, evaluating to 22 before foo is again incremented.
var foo = 10; console.log(foo, foo++ + ++foo, foo);
foo++ + ++foo
10 + 12
By the time we reach ++foo, the value has already incriminated from foo++
var foo = 10; console.log(foo, foo + ++foo, foo);
foo + ++foo
10 + 11
foo is incremented before we add it to foo, thus giving us 10 + 11
SUMMARY
Basically it all depends on what the current value of foo is when you add them together.

Javascript function. Don't understand how function inside self-function work

would like to ask about a JavaScript function.
I don't understand below function, I thought at line 4 fib(n-1) will return 1 and the latter fib(n-2) will return 0, and then they both add together as 1.
May I know why the final result for f(10); will be 55, can't get my head around this.
Anyone can help to explain to me what happening behind the scene, please?
Thanks! ;)
var f = function fib(n) {
if (n === 0) return 0;
if (n === 1) return 1;
if (n > 1) return fib(n - 1) + fib(n - 2); // *2
};
f(10); // 55
ref: https://slides.com/concise/js/fullscreen#/35
Like this. This is a typical recursive function, with two base cases and one recursive step.
Remember that if n is 10, then fib(n - 1) is fib(9), and so on:
fib(10) = fib(9) + fib(8) = 34 + 21 = 55
fib(9) = fib(8) + fib(7) = 21 + 13 = 34
fib(8) = fib(7) + fib(6) = 13 + 8 = 21
fib(7) = fib(6) + fib(5) = 8 + 5 = 13
fib(6) = fib(5) + fib(4) = 5 + 3 = 8
fib(5) = fib(4) + fib(3) = 3 + 2 = 5
fib(4) = fib(3) + fib(2) = 2 + 1 = 3
fib(3) = fib(2) + fib(1) = 1 + 1 = 2
fib(2) = fib(1) + fib(0) = 1 + 0 = 1
fib(1) = 1
fib(0) = 0
Side note: Although your example is a good illustration of recursive functions, it's an extremely inefficient way to calculate fibonacci numbers. A much better approach is to use memoization to eliminate the bulk of the inefficiency:
var fib = (function () {
var cache = [0, 1];
return function fib(num) {
if (!(num in cache)) {
cache[num] = fib(num - 1) + fib(num - 2);
}
return cache[num];
};
})();
console.log(fib(10));
http://jsperf.com/fibonacci-memoization-2015-04-01
this is called "recursive function" which one function calls itself.
basically there is no restriction (in terms of the OS) of doing so, a function basically gets interpreted/compiled to assembly code , and this assembly code can be copied and re-run with different (or the same) arguments.

Understanding Javascript Functions and Closure [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 9 years ago.
In the following example, how is y given the value of 1? I added some logging to see values and don't understand how/where y is assigned...
(function() {
function foo(x) {
var callNum = 0;
var baz = 3;
return function (y) {
callNum++;
console.log("callNum: " + callNum);
console.log("y: " + y);
console.log("baz: " + baz);
console.log("x: " + x);
console.log(x + y + (++baz));
}
}
var moo = foo(2); // moo is now a closure.
moo(1);
moo(1);
})();
Here's the fiddle output log:
callNum: 1
y: 1
baz: 3
x: 2
7
callNum: 2
y: 1
baz: 4
x: 2
8
foo() returns a function. This returned function accepts a single argument, the y you are concerned with.
So when you do this:
// returns a function that accepts `y` with `x` shared via closure
var moo = foo(2);
// execute the inner function, passing in a value for `y`.
moo(1);
foo(2) returns a function. x is now 2. moo is now a function that accepts a value for y, and you pass in 1. So y is now 1.
To think of it another way, you can invoke your inner function by doing:
foo(x)(y);
Or with the values you are using:
foo(2)(1);
So, in answer to your question, y gets set to 1 when you do:
moo(1);
In your code:
(function() {
function foo(x) {
var callNum = 0;
var baz = 3;
These are the parameters that matter (x, callNum and baz). They form closures involving the following function:
return function (y) {
This function has a closure to each of the outer local variables (including moo and foo).
callNum++;
console.log("callNum: " + callNum);
console.log("y: " + y);
console.log("baz: " + baz);
console.log("x: " + x);
console.log(x + y + (++baz));
}
}
There are also closures involving moo and both the above functions, however it's not used so is irrelevant to the outcome.
var moo = foo(2); // moo is now a closure.
The rest is answered by Alex.

Categories

Resources