Home > Software design >  Explain JavaScript code process in plain English
Explain JavaScript code process in plain English

Time:10-09

I'm learning on Udacity and they have a quiz which I couldn't pass myself. I decided to look at the provided solution but I need to understand the process of the code (I understand some of it). Here it is:

// creates a line of * for a given length
function makeLine(length) {
    var line = "";
    for (var j = 1; j <= length; j  ) {
        line  = "* ";
    }
    return line   "\n";
}

// your code goes here.  Make sure you call makeLine() in your own code.
function buildTriangle(length) {
    // Let's build a huge string equivalent to the triangle
    var triangle = "";

    //Let's start from the topmost line
    var lineNumber = 1;

    for(lineNumber=1; lineNumber<=length; lineNumber  ){
        // We will not print one line at a time.
        // Rather, we will make a huge string that will comprise the whole triangle
        triangle = triangle   makeLine(lineNumber);
    }
    return triangle;
}

// test your code by uncommenting the following line
// Note that the function buildTriangle() must return a string 
// because the console.log() accepts a string argument
console.log(buildTriangle(10));

I understand that makeLine() will create line of asterisks based on the value of length that passed to it when it gets called inside buildTriangle()

But I don't understand how this line works:

triangle = triangle   makeLine(lineNumber);

Is it not working like the line in makeLine () which is

line  = "* ";

What's the difference between using = and triangle = triangle makeLine(lineNumber)? If they work same then the output should be wrong.

Also please correct me if I'm wrong in my understanding to the variable length in makeLine(length) and buildTriangle (length). Are they different variables because of different scope? Can I change the name of the variable in buildTriangle function to be something like buildTriangle (passedValueToMakeLineFunc)?

Finally it would be highly appreciated if someone imitate the JavaScript engine and described how it will handle that code step by step in plain English.

CodePudding user response:

what's the difference between using = and triangle = triangle makeLine(lineNumber)

These are equivalent:

triangle = triangle   makeLine(lineNumber);
triangle  = makeLine(lineNumber);

…the variable length in makeLine(length) and buildTriangle (length) ... are they different variables…

Correct.

  1. The variables are entirely independent and
  2. you can call them whatever you want.

step by step in plain English

Apologies if this is too verbose or not what you had in mind:

  • declare functions makeLine and buildTriangle (define but do not execute)
  • invoke buildTriangle with a single argument (10) to resolve value to be passed to console.log

Execution of buildTriangle:

function buildTriangle(length) {
    // Let's build a huge string equivalent to the triangle
    var triangle = "";

    //Let's start from the topmost line
    var lineNumber = 1;

    for(lineNumber=1; lineNumber<=length; lineNumber  ){
        // We will not print one line at a time.
        // Rather, we will make a huge string that will comprise the whole triangle
        triangle = triangle   makeLine(lineNumber);
    }
    return triangle;
}
  • begin execution of buildTriangle with length = 10
  • declare a variable called triangle with an initial empty string value
  • declare a variable called lineNumber with an initial value of 1.
  • initialize for loop: set variable lineNumber to 1 (again)
  • evaluate for loop condition. is lineNumber less than or equal to length (10)?
  • lineNumber is 1, which is less than 10, so loop condition is true. execute loop body.
  • evaluate makeLine(1) (lineNumber is 1)

Execution of makeLine:

function makeLine(length) {
    var line = "";
    for (var j = 1; j <= length; j  ) {
        line  = "* ";
    }
    return line   "\n";
}
  • begin execution of makeLine with length = 1
  • declare variable called line and initialize to empty string
  • begin for loop: declare and initialize variable j with initial value 1
  • evaluate for loop condition. is j less than or equal to length (1)?
  • j is 1, which is equal to 1, so loop condition is true. execute loop body.
  • append "* " to line. (line is now "* ")
  • increment j. j is now 2.
  • evaluate for loop condition. is j less than or equal to length (1)?
  • j is 2. condition is false. exit loop.
  • return line value with a newline appended: ("* \n")

(Resume buildTriangle execution)

  • set triangle to its current value (empty string) plus resolved makeLine value: triangle is now "* \n"
  • end of loop body. run post-loop expression (lineNumber )
  • set lineNumber to 2
  • evaluate for loop condition. is lineNumber less than or equal to length (10)?
  • lineNumber is 2, which is less than 10, so loop condition is true. execute loop body.
  • evaluate makeLine(2) (lineNumber is 2)

Execution of makeLine:

  • begin execution of makeLine with length = 2
  • declare variable called line and initialize to empty string
  • begin for loop: declare and initialize variable j with initial value 1
  • evaluate for loop condition. is j less than or equal to length (2)?
  • j is 1, which is less than 2, so loop condition is true. execute loop body.
  • append "* " to line. (line is now "* ")
  • increment j. j is now 2.
  • evaluate for loop condition. is j less than or equal to length (2)?
  • j is 2, which is equal to 2, so loop condition is true. execute loop body.
  • append "* " to line. (line is now "* * ")
  • increment j. j is now 3.
  • evaluate for loop condition. is j less than or equal to length (2)?
  • j is 3. condition is false. exit loop.
  • return line value with a newline appended: ("* * \n")

(Resume buildTriangle execution)

  • set triangle to its current value "* \n" plus resolved makeLine value: triangle is now "* \n* * \n"
  • end of loop body. run post-loop expression (lineNumber )
  • set lineNumber to 3
  • evaluate for loop condition. is lineNumber less than or equal to length (10)?
  • lineNumber is 3, which is less than 10, so loop condition is true. execute loop body.
  • evaluate makeLine(3) (lineNumber is 3)

Repeat steps above until lineNumber reaches 11 and loop exits.

  • return value of triangle to caller and exit buildTriangle. At this point the value of triangle is:
* 
* * 
* * * 
* * * * 
* * * * * 
* * * * * * 
* * * * * * * 
* * * * * * * * 
* * * * * * * * * 
* * * * * * * * * * 
  • invoke console.log with the value returned by buildTriangle.
  • exit

Your example included here for reference:

// creates a line of * for a given length
function makeLine(length) {
    var line = "";
    for (var j = 1; j <= length; j  ) {
        line  = "* ";
    }
    return line   "\n";
}

// your code goes here.  Make sure you call makeLine() in your own code.
function buildTriangle(length) {
    // Let's build a huge string equivalent to the triangle
    var triangle = "";

    //Let's start from the topmost line
    var lineNumber = 1;

    for(lineNumber=1; lineNumber<=length; lineNumber  ){
        // We will not print one line at a time.
        // Rather, we will make a huge string that will comprise the whole triangle
        triangle = triangle   makeLine(lineNumber);
    }
    return triangle;
}

// test your code by uncommenting the following line
// Note that the function buildTriangle() must return a string 
// because the console.log() accepts a string argument
console.log(buildTriangle(10));

CodePudding user response:

Addition assignment operator ( =)

someVar = "someString" is the same as someVar = someVar "someString"

Go ahead and replace your example with triangle = makeLine(lineNumber) and you'll see you get the same triangle.

The 2 lengths

In this case, they are both parameters to the functions makeLine and buildTriangle.

  • Function parameters are scoped to the function block, meaning they are only available inside the function, not accessible outside.
  • Name them as you like, this has no effect outside of the function block.
  • Note that if a length parameter did in fact exist outside of the function declarations, the length parameter would over/hide the external variable from use inside the function.
var length = 4;
console.log("outer", length); // 4
function someFunction(length) {
  console.log("inner", length); // 5
}
someFunction(5);
console.log("outer", length); // 4

Code in english

I'm going to assume this is a little too detailed in some places and maybe not enough in others. Enjoy the story!

  1. The makeLine function is declared (but not run yet)
  2. The buildTriangle function is declared (but not run yet)
  3. We hit a console.log() with a param of a function call (buildTriangle(10)). We'll execute that function, and the result of it will be passed to the log function call.
  4. We've stepped into the buildTriangle function with a param length of value 10.
  5. We make a triangle variable we'll build out the entire triangle into, new lines and all, initialized to an empty string.
  6. We declare a lineNumber variable set to 1.
    • This one is just to mess with you
    • It did not need to be done before the for loop, would have been just the same to for (var lineNumber=1; lineNumber<=length; lineNumber ){ ... } and not declare it before hand.
    • It does not matter what it was or wasn't initialized to as the for loop sets it to 1 as it starts.
  7. We hit a for loop, for(lineNumber=1; lineNumber<=length; lineNumber )
    • We set lineNumber to 1
    • We will continue to run another iteration of this loop until lineNumber is <= length (10) (So up until and including 10)
    • We will, upon the completion of each iteration, before checking the continuation condition, increment the lineNumber by 1 (lineNumber ).
  8. For each iteration of the loop (lineNumber values 1,2,3,4,5,6,7,8,9,10) we execute triangle = triangle makeLine(lineNumber); Which just takes the current triangle string, appends the result of makeLine(lineNumber) to it, and assigns that value to triangle.
  9. We've stepped into the makeLine function with a param length of value 1.
    • Note at this point, the only variable available to our scope is the length param. (Besides the 2 functions I suppose)
  10. We initialize a new variable line to an empty string.
    • Note, this will be a brand new / separate line variable for every execution of this function Sounds like this is where you maybe hung up?
    • Since the line variable is declared inside the function, it is scoped there, and is not accessible outside or across function executions.
    • This would be different if it were declared outside of the function and not reset at the begining. Then every execution would continue to just add on.
  11. We encounter another for loop, this time with the iterator variable declared inside (j) for (var j = 1; j <= length; j ) { ... }
    • We declare and initialize j to 1
    • We will continue to run another iteration of this loop until j is <= length (1) (So just 1 on this makeLine execution, subsequent times, 1-2, 1-3, ..., 1-10)
    • We will, upon the completion of each iteration, before checking the continuation condition, increment the j by 1 (j ).
  12. For each iteration of the loop we execute line = "* "; which just takes the current line string, appends a "* " and assigns that value to line.
  13. After this loop we encounter a return statement that is the result of combining our build out line with a newline character ("\n").
  14. Assuming we've made it through all of our buildTriangle for loop iterations, we encounter our return statement and return the build out triangle.
  15. We've now supplied the return value to be supplied as the parameter to console.log.
  16. done.
  • Related