Vlad Dev Vlad Dev - 7 months ago 8
Javascript Question

Functions in javascript and scopes

Here i have simplified my problem to this code. I need to build a table. I have 3 functions(one,two,three) that have specific functionality, and i have a main function that builds a table from the return of this 3 functions. However i don't fully understand how to finish this.

function foo(one,two,three){
var result = "";
for (var i=0;i<arguments.length;i++){
result+= arguments[i](true);
result+= arguments[i](false);
}
console.log(result);
}
foo(one);


There could be 2 more functions, but in this case it doesn't matter i wrote only one. So the one() can accept 2 arguments(true or false) and

function one(arg){
if(arg == true){
this.result += "1-true";
} else if(arg ==false){
this.result += "1-false";
}
return this.result;
}

Answer

When you call a function, it won't inherit the scope from the calling code, so the property this.result in the one function won't be the same as the local variable result in the foo function.

Unless you call a function as a method of an object, the context of the function (this) will be the global window object. Inside the one function this.result will be the same as window.result. As the window object is the global context, you will create a global variable named result.

The variable result declared inside the foo function is local to that function, and it's separate from the global result variable. From the one function you can't even reach the result variable in foo function at all.

As the one function is using a global variable that is never assigned a value, it will contain undefined from the start. Adding "1-true" to it will convert undefined into the string "undefined" and the result is "undefined1-true". In the next call to one the value in the global variable is still there, so it will add "1-false" to it, making it "undefined1-true1false". As the foo function adds the values from the first and the second call to one, the result is "undefined1-trueundefined1-true1-false".

If you would use the global variable in both functions so that they used the same variable (which is what it seems that you tried to do), you would get a different result. The one function would add "1-true" to the variable and then return the variable. The foo function would then add the returned value to the variable, making it "1-true1-true". The next call to one would add "1-false" to the variable making it "1-true1-true1-false" and then return the value of the variable, which the foo function adds to the variable, making it "1-true1-true1-false1-true1-true1-false".

Instead of adding to the variable in both functions, you should just return a string from the one function, and put the strings together in the foo function:

function foo(one,two,three) {
  var result = "";
  for (var i = 0; i < arguments.length; i++) {
    result += arguments[i](true);
    result += arguments[i](false);
  }
  console.log(result);
}
foo(one);

function one(arg) {
  if(arg == true) {
    return "1-true";
  } else if (arg == false) {
    return "1-false";
  }
}

Note: Instead of using if (arg == true) you can just use if (arg), and the else if() can just be an else:

function one(arg) {
  if(arg) {
    return "1-true";
  } else {
    return "1-false";
  }
}

You can also use the conditional operator to get the same result:

function one(arg) {
  return arg ? "1-true" : "1-false";
}

If you still want to use a variable in the one function, you don't need to use the += operator as you only have one string. You can just assign the value:

function one(arg) {
  var result;
  if(arg) {
    result = "1-true";
  } else {
    result = "1-false";
  }
  return result;
}