0

Here is some code I'm really having issues understanding (JavaScript)

function func(x) {
     var y = x + 2;
     z = 20;
     return function(y) {
         var z = y * 3; 
         return function(z) {
             return x + y + z;
         };
     }; 
 }
 console.log(func(3)(4)("z"));

output: 7z

I have a lot of experience with Java (only Java) and I'm really having issues understanding how JavaScript works. I tried debugging and going step by step over code but I'm still very confused.

One sub-question I have is whether y on line 2 is the same y as in return function(y) line.

Any help would be greatly appreciated!

Jay Patel
  • 1,098
  • 7
  • 22
James
  • 19
  • 2
  • 2
    You need to explain what part exactly confuses you. Are you aware of closures and how they work? What have you seen when you stepped through the code with the debugger? What did you expect the output to be instead? – UnholySheep Jan 01 '22 at 12:34
  • My best guess about your confusion is that you expect the variable declarations/assignments to have an effect, but they get shadowed by other variables in the closures – UnholySheep Jan 01 '22 at 12:36
  • Keep in mind that all of the `z`s except the last are red herrings, otherwise read up on [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) as @UnholySheep mentioned, and on [scope of var, let](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var), and possibly [currying](https://stackoverflow.com/questions/36314/what-is-currying) – pilchard Jan 01 '22 at 12:36
  • If not mistaken, that looks like a fancier call-back. Am I wrong? If this helps author, this isn't seen much in traditional coding, you make optimizations like this rarely to squeeze out a few complexity points. – BGPHiJACK Jan 01 '22 at 12:40
  • 1
    @BGPHiJACK not really a callback. Just a curried function. https://stackoverflow.com/q/18234491 – VLAZ Jan 01 '22 at 12:43
  • Dope, not really seeing people code this way so it's interesting to see. Thank you! :) – BGPHiJACK Jan 01 '22 at 12:51
  • Javascript is a veneer of Java-like syntax laid over what is essentially a Lisp engine. That is what is going on here, this code demonstrates that pretty well. – RBarryYoung Jan 01 '22 at 13:06

4 Answers4

1

When looking for value of variable, JS will pick it from the closest scope going upwards.

In line 5, the y is the y from the argument and not from the upper scope. That value although is enclosed (read closures), is not being used here.

Same, goes for the z below.

When running the statement return x + y + z; the outer scope (that is shadowing the variable y) is destroyed. So the other closes values are used ergo 3 and 4.

function func(x) {
     var y = x + 2;
     z = 20;
     return function(y) {
         var z = y * 3; 
         return function(z) {
             return x + y + z;
         };
     }; 
 }
console.log(func(3)(4)("z"));
Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
1
  1. Get yourself a good code editor for JS (vscode is great and free)
  2. Go to a variable, press F2 and give it a more unique name.
  3. check which occurrences are affected.
  4. "use strict"! what is Strict Mode?

This is what your code then might look like.

"use strict";

function func(arg0) {
  var var1 = arg0 + 2;
  // undeclared/global variable
  z = 20; 
  return function (arg2) {
    var var2 = arg2 * 3;
    return function (arg4) {
      return arg0 + arg2 + arg4;
    };
  };
}

console.log(func(3)(4)("z"));

I think this makes it clearer what variable/parameter is what.

And if you run this, you'll get an error regarding your usage of the undeclared variable z, because strict mode doesn't allow this, whereas sloppy mode would create/use a global variable.

Sidenote: Take a look at Typescript. Coming from such a strict language like Java you might prefer the ability to type your code.

Thomas
  • 11,958
  • 1
  • 14
  • 23
0

What I understand is from this function call is

fun(3)(4)("Z");

first call

x = 3;
y = 5;
z = 20;

second call

y=4; 
z=60;
x=3;

third call

x=3; // from first function parameter
y=4; // y value from second function parameter
z="z" // third function parameter

In the it will return

3+4+"Z" = 7z

as string

All pre calculated values are useless

0

var is function scope, which means if you redeclare a variable in a function, it will be inside that function. It won’t mutate the outer scopes or global scopes same-named variable.

variableA = 16;
function incrementOne (localVariable) {
    var variableA = localVariable + 1;
    console.log("variableA internal", variableA);
}
incrementOne(10);
console.log("variableA", variableA);

And my request is not to use any syntax in js like this

variable = 16;

better use var if u really don't want to use let or cons.

var variable = 16

I can assure this that let and const will resolve your maximum understandings. Thanks.