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.
- The variables are entirely independent and
- 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
makeLineandbuildTriangle(define but do not execute) - invoke
buildTrianglewith a single argument (10) to resolve value to be passed toconsole.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
buildTrianglewithlength = 10 - declare a variable called
trianglewith an initial empty string value - declare a variable called
lineNumberwith an initial value of1. - initialize
forloop: set variablelineNumberto1(again) - evaluate
forloop condition. islineNumberless than or equal tolength(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
makeLinewithlength = 1 - declare variable called
lineand initialize to empty string - begin
forloop: declare and initialize variablejwith initial value1 - evaluate
forloop condition. isjless than or equal tolength(1)? - j is 1, which is equal to 1, so loop condition is true. execute loop body.
- append
"* "toline. (lineis now"* ") - increment
j.jis now2. - evaluate
forloop condition. isjless than or equal tolength(1)? jis2. condition is false. exit loop.- return
linevalue with a newline appended: ("* \n")
(Resume buildTriangle execution)
- set
triangleto its current value (empty string) plus resolvedmakeLinevalue:triangleis now"* \n" - end of loop body. run post-loop expression (lineNumber )
- set
lineNumberto 2 - evaluate
forloop condition. islineNumberless than or equal tolength(10)? lineNumberis2, which is less than10, so loop condition is true. execute loop body.- evaluate
makeLine(2)(lineNumber is 2)
Execution of makeLine:
- begin execution of
makeLinewithlength = 2 - declare variable called
lineand initialize to empty string - begin
forloop: declare and initialize variablejwith initial value1 - evaluate
forloop condition. isjless than or equal tolength(2)? - j is 1, which is less than 2, so loop condition is true. execute loop body.
- append
"* "toline. (lineis now"* ") - increment
j.jis now2. - evaluate
forloop condition. isjless than or equal tolength(2)? - j is 2, which is equal to 2, so loop condition is true. execute loop body.
- append
"* "toline. (lineis now"* * ") - increment
j.jis now3. - evaluate
forloop condition. isjless than or equal tolength(2)? jis3. condition is false. exit loop.- return
linevalue with a newline appended: ("* * \n")
(Resume buildTriangle execution)
- set
triangleto its current value"* \n"plus resolvedmakeLinevalue:triangleis now"* \n* * \n" - end of loop body. run post-loop expression (lineNumber )
- set
lineNumberto 3 - evaluate
forloop condition. islineNumberless than or equal tolength(10)? lineNumberis3, which is less than10, 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
triangleto caller and exitbuildTriangle. At this point the value oftriangleis:
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
- invoke
console.logwith the value returned bybuildTriangle. - 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!
- The
makeLinefunction is declared (but not run yet) - The
buildTrianglefunction is declared (but not run yet) - 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.
- We've stepped into the
buildTrianglefunction with a param length of value 10. - We make a
trianglevariable we'll build out the entire triangle into, new lines and all, initialized to an empty string. - 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.
- We hit a for loop,
for(lineNumber=1; lineNumber<=length; lineNumber )- We set
lineNumberto 1 - We will continue to run another iteration of this loop until
lineNumberis <= length (10) (So up until and including 10) - We will, upon the completion of each iteration, before checking the continuation condition, increment the
lineNumberby 1 (lineNumber).
- We set
- 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 currenttrianglestring, appends the result ofmakeLine(lineNumber)to it, and assigns that value totriangle. - We've stepped into the
makeLinefunction with a param length of value 1.- Note at this point, the only variable available to our scope is the
lengthparam. (Besides the 2 functions I suppose)
- Note at this point, the only variable available to our scope is the
- We initialize a new variable
lineto 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
linevariable 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.
- 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
jto 1 - We will continue to run another iteration of this loop until
jis <= 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
jby 1 (j).
- We declare and initialize
- For each iteration of the loop we execute
line = "* ";which just takes the currentlinestring, appends a "* " and assigns that value toline. - After this loop we encounter a return statement that is the result of combining our build out line with a newline character ("\n").
- Assuming we've made it through all of our
buildTrianglefor loop iterations, we encounter our return statement and return the build outtriangle. - We've now supplied the return value to be supplied as the parameter to console.log.
- done.
