#javascript #reactjs
Вопрос:
Я учусь на Udacity, и у них есть тест, который я сам не смог пройти. Я решил взглянуть на предоставленное решение, но мне нужно понять процесс написания кода (я кое-что понимаю). Вот он:
// 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));
Я понимаю, что makeLine() создаст строку звездочек на основе значения длины, которое передается ей при вызове внутри buildTriangle()
Но я не понимаю, как работает эта линия:
triangle = triangle makeLine(lineNumber);
Разве это не работает так, как строка в makeLine (), которая
line = "* ";
В чем разница между использованием =
и triangle = triangle makeLine(lineNumber)
? Если они работают одинаково, то вывод должен быть неправильным.
Также, пожалуйста, поправьте меня, если я ошибаюсь в своем понимании переменной длины в makeLine(длина) и buildTriangle (длина). Являются ли они разными переменными из-за разной области видимости? Могу ли я изменить имя переменной в функции buildTriangle на что-то вроде buildTriangle (passedValueToMakeLineFunc)?
Наконец, было бы весьма признателен, если бы кто-нибудь подражал движку JavaScript и описал, как он будет обрабатывать этот код шаг за шагом на простом английском языке.
Комментарии:
1. Быстрый ответ: Попробуйте отредактировать код, чтобы он был
triangle = makeLine(lineNumber);
. Вы должны заметить, что результат такой же, как и при использованииtriangle = triangle makeLine(lineNumber);
!2. «Являются ли они разными переменными из — за разной области видимости?» — да, это правильно, вы можете изменить имя переменной на любое другое допустимое имя переменной
3. Хорошо, Джон Кугельман, понял. Tq 🙂 @DemiPixel да, работал так же. но я все еще в замешательстве. Первый цикл в функции buildTriangle вызывает функцию makeLine, которая вернет первую строку звездочки «* » с новой строкой «n «, поэтому во втором цикле переданное значение в функцию makeLine() увеличивается на 1, поэтому она вернет 2 звездочки»**», но так как мы использовали =, 2 звездочки будут добавлены к первой «* » из первого цикла и вернут 3 звездочки вместо 2 для второй строки. Я думаю, что мне нужно больше объяснений того, как работает = или как каждый цикл цикла связан с предыдущим раундом.
Ответ №1:
в чем разница между использованием = и треугольником = треугольник линия(номер строки)
Они эквивалентны:
triangle = triangle makeLine(lineNumber);
triangle = makeLine(lineNumber);
…переменная длина в makeLine(длина) и buildTriangle (длина) … являются ли они разными переменными…
Правильный.
- Переменные полностью независимы и
- вы можете называть их как хотите.
шаг за шагом на простом английском языке
Приносим извинения, если это слишком многословно или не то, что вы имели в виду:
- объявляйте функции
makeLine
иbuildTriangle
(определяйте, но не выполняйте) - вызовите
buildTriangle
с помощью одного аргумента (10
), чтобы разрешить значение, которое будет переданоconsole.log
Выполнение 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;
}
- начните выполнение
buildTriangle
сlength = 10
- объявите переменную, вызываемую
triangle
с начальным пустым строковым значением - объявите переменную, вызываемую
lineNumber
с начальным значением1
. for
цикл инициализации: установите переменнуюlineNumber
в1
(снова)- оцените
for
состояние цикла.lineNumber
меньше или равноlength
(10)? - Номер строки равен 1, что меньше 10, поэтому условие цикла верно. выполните тело цикла.
- оценить
makeLine(1)
(номер строки равен 1)
Выполнение makeLine:
function makeLine(length) {
var line = "";
for (var j = 1; j <= length; j ) {
line = "* ";
}
return line "n";
}
- начните выполнение
makeLine
сlength = 1
- объявите вызываемую переменную
line
и инициализируйте ее в пустую строку for
цикл начала: объявить и инициализировать переменнуюj
с начальным значением1
- оцените
for
состояние цикла.j
меньше или равноlength
(1)? - j равно 1, что равно 1, поэтому условие цикла верно. выполните тело цикла.
- добавить
"* "
кline
. (line
сейчас"* "
) - прирост
j
.j
это сейчас2
. - оцените
for
состояние цикла.j
меньше или равноlength
(1)? j
является2
. условие ложно. выходная петля.- возвращаемое
line
значение с добавлением новой строки: ("* n"
)
(Возобновить buildTriangle
выполнение)
- установите
triangle
его текущее значение (пустая строка) плюс разрешенноеmakeLine
значение:triangle
теперь"* n"
- конец тела петли. выполните выражение после цикла (номер строки )
- установлено
lineNumber
значение 2 - оцените
for
состояние цикла.lineNumber
меньше или равноlength
(10)? lineNumber
есть2
, что меньше , чем10
, поэтому условие цикла верно. выполните тело цикла.- оценить
makeLine(2)
(номер строки равен 2)
Выполнение makeLine:
- начните выполнение
makeLine
сlength = 2
- объявите вызываемую переменную
line
и инициализируйте ее в пустую строку for
цикл начала: объявить и инициализировать переменнуюj
с начальным значением1
- оцените
for
состояние цикла.j
меньше или равноlength
(2)? - j равно 1, что меньше 2, поэтому условие цикла верно. выполните тело цикла.
- добавить
"* "
кline
. (line
сейчас"* "
) - прирост
j
.j
это сейчас2
. - оцените
for
состояние цикла.j
меньше или равноlength
(2)? - j равно 2, что равно 2, поэтому условие цикла верно. выполните тело цикла.
- добавить
"* "
кline
. (line
сейчас"* * "
) - прирост
j
.j
это сейчас3
. - оцените
for
состояние цикла.j
меньше или равноlength
(2)? j
является3
. условие ложно. выходная петля.- возвращаемое
line
значение с добавлением новой строки: ("* * n"
)
(Возобновить buildTriangle
выполнение)
- установите
triangle
его текущее значение"* n"
плюс разрешенноеmakeLine
значение:triangle
теперь"* n* * n"
- конец тела петли. выполните выражение после цикла (номер строки )
- установлено
lineNumber
значение 3 - оцените
for
состояние цикла.lineNumber
меньше или равноlength
(10)? lineNumber
есть3
, что меньше , чем10
, поэтому условие цикла верно. выполните тело цикла.- оценить
makeLine(3)
(номер строки равен 3)
Повторяйте описанные выше шаги, пока номер строки не достигнет 11 и цикл не завершится.
- верните значение
triangle
вызывающему абоненту и выйдитеbuildTriangle
. На данный момент значениеtriangle
равно:
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
- вызовите
console.log
со значением, возвращеннымbuildTriangle
. - выход
Ваш пример приведен здесь для справки:
// 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));
Комментарии:
1. Просто наткнулся на этот вопрос во время случайного изучения. Я не прочитал весь вопрос и ответ, но я все равно благодарен @ray-hatfield за то, что вы нашли время, чтобы опубликовать ответ. 👏
Ответ №2:
Оператор присваивания сложения ( =)
someVar = "someString"
это то же самое, что someVar = someVar "someString"
Продолжайте и замените свой пример на triangle = makeLine(lineNumber)
, и вы увидите, что получите тот же треугольник.
2 с length
В этом случае они оба являются параметрами функций makeLine
и buildTriangle
.
- Параметры функции ограничены областью действия функционального блока, что означает, что они доступны только внутри функции, недоступны снаружи.
- Называйте их как хотите, это не имеет никакого эффекта за пределами функционального блока.
- Обратите внимание, что если бы параметр длины действительно существовал вне объявлений функций, параметр длины закрывал бы/скрывал внешнюю переменную от использования внутри функции.
var length = 4;
console.log("outer", length); // 4
function someFunction(length) {
console.log("inner", length); // 5
}
someFunction(5);
console.log("outer", length); // 4
Код на английском языке
Я предполагаю, что в некоторых местах это слишком подробно, а в других, возможно, недостаточно. Наслаждайтесь этой историей!
makeLine
Функция объявлена (но еще не запущена)buildTriangle
Функция объявлена (но еще не запущена)- Мы нажимаем console.log() с параметром вызова функции (buildTriangle(10)). Мы выполним эту функцию, и ее результат будет передан вызову функции журнала.
- Мы вошли в
buildTriangle
функцию с длиной параметра, равной 10. - Мы создаем
triangle
переменную, в которую мы построим весь треугольник, новые строки и все остальное, инициализированные пустой строкой. - Мы объявляем переменную lineNumber равной 1.
- Этот просто для того, чтобы поссориться с тобой
- Это не нужно было делать перед циклом for, было бы то же самое, чтобы
for (var lineNumber=1; lineNumber<=length; lineNumber ){ ... }
и не объявлять об этом раньше времени. - Не имеет значения, для чего он был инициализирован или не был инициализирован, поскольку цикл for устанавливает значение 1 при запуске.
- Мы попали в петлю for,
for(lineNumber=1; lineNumber<=length; lineNumber )
- Мы установили
lineNumber
значение 1 - Мы продолжим выполнять еще одну итерацию этого цикла, пока
lineNumber
не будет - По завершении каждой итерации, перед проверкой условия продолжения, мы увеличим значение
lineNumber
на 1 (lineNumber
).
- Мы установили
- Для каждой итерации цикла (значения номеров строк 1,2,3,4,5,6,7,8,9,10) мы выполняем
triangle = triangle makeLine(lineNumber);
, который просто берет текущуюtriangle
строку, добавляетmakeLine(lineNumber)
к ней результат и присваивает это значениеtriangle
. - Мы вошли в
makeLine
функцию с длиной параметра, равной 1.- Обратите внимание, что на данный момент единственной переменной, доступной для нашей области видимости, является
length
параметр. (Помимо 2 функций, я полагаю)
- Обратите внимание, что на данный момент единственной переменной, доступной для нашей области видимости, является
- Мы инициализируем новую переменную
line
в пустую строку.- Обратите внимание, что это будет совершенно новая / отдельная переменная строки для каждого выполнения этой функции Звучит так, как будто вы, возможно, повесили трубку?
- Поскольку
line
переменная объявлена внутри функции, область ее действия находится там и недоступна снаружи или во время выполнения функции. - Это было бы по-другому, если бы оно было объявлено вне функции и не сбрасывалось в начале. Тогда каждое выполнение продолжало бы просто добавляться.
- Мы сталкиваемся с другим циклом for, на этот раз с переменной итератора, объявленной внутри (j)
for (var j = 1; j <= length; j ) { ... }
- Мы объявляем и инициализируем
j
значение 1 - Мы продолжим выполнять еще одну итерацию этого цикла, пока
j
не будет - По завершении каждой итерации, перед проверкой условия продолжения, мы увеличим значение
j
на 1 (j
).
- Мы объявляем и инициализируем
- Для каждой выполняемой нами итерации цикла
line = "* ";
, которая просто берет текущуюline
строку, добавляет «* » и присваивает это значениеline
. - После этого цикла мы сталкиваемся с оператором return, который является результатом объединения нашей строки построения с символом новой строки («n»).
- Предполагая, что мы прошли все наши
buildTriangle
итерации цикла for, мы сталкиваемся с нашим оператором return и возвращаем сборкуtriangle
. - Теперь мы указали возвращаемое значение, которое будет указано в качестве параметра console.log.
- Выполнено.