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
makeLine
andbuildTriangle
(define but do not execute) - invoke
buildTriangle
with 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
buildTriangle
withlength = 10
- declare a variable called
triangle
with an initial empty string value - declare a variable called
lineNumber
with an initial value of1
. - initialize
for
loop: set variablelineNumber
to1
(again) - evaluate
for
loop condition. islineNumber
less 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
makeLine
withlength = 1
- declare variable called
line
and initialize to empty string - begin
for
loop: declare and initialize variablej
with initial value1
- evaluate
for
loop condition. isj
less than or equal tolength
(1)? - j is 1, which is equal to 1, so loop condition is true. execute loop body.
- append
"* "
toline
. (line
is now"* "
) - increment
j
.j
is now2
. - evaluate
for
loop condition. isj
less than or equal tolength
(1)? j
is2
. 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 resolvedmakeLine
value:triangle
is now"* \n"
- end of loop body. run post-loop expression (lineNumber )
- set
lineNumber
to 2 - evaluate
for
loop condition. islineNumber
less than or equal tolength
(10)? lineNumber
is2
, which is less than10
, so loop condition is true. execute loop body.- evaluate
makeLine(2)
(lineNumber is 2)
Execution of makeLine:
- begin execution of
makeLine
withlength = 2
- declare variable called
line
and initialize to empty string - begin
for
loop: declare and initialize variablej
with initial value1
- evaluate
for
loop condition. isj
less than or equal tolength
(2)? - j is 1, which is less than 2, so loop condition is true. execute loop body.
- append
"* "
toline
. (line
is now"* "
) - increment
j
.j
is now2
. - evaluate
for
loop condition. isj
less than or equal tolength
(2)? - j is 2, which is equal to 2, so loop condition is true. execute loop body.
- append
"* "
toline
. (line
is now"* * "
) - increment
j
.j
is now3
. - evaluate
for
loop condition. isj
less than or equal tolength
(2)? j
is3
. condition is false. exit loop.- return
line
value with a newline appended: ("* * \n"
)
(Resume buildTriangle
execution)
- set
triangle
to its current value"* \n"
plus resolvedmakeLine
value:triangle
is now"* \n* * \n"
- end of loop body. run post-loop expression (lineNumber )
- set
lineNumber
to 3 - evaluate
for
loop condition. islineNumber
less than or equal tolength
(10)? lineNumber
is3
, 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
triangle
to caller and exitbuildTriangle
. At this point the value oftriangle
is:
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
- invoke
console.log
with 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 length
s
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
makeLine
function is declared (but not run yet) - The
buildTriangle
function 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
buildTriangle
function with a param length of value 10. - We make a
triangle
variable 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
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
).
- 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 currenttriangle
string, appends the result ofmakeLine(lineNumber)
to it, and assigns that value totriangle
. - 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)
- Note at this point, the only variable available to our scope is the
- 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.
- 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
).
- We declare and initialize
- For each iteration of the loop we execute
line = "* ";
which just takes the currentline
string, 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
buildTriangle
for 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.