Почему вы должны указывать переменную снова после каждого приглашения, если вы вычитаете из нее число? JavaScript - PullRequest
0 голосов
/ 24 января 2020

Это было очень трудно выразить словами, но я работаю над проблемой безумных либов, и цель состоит в том, чтобы 3 раза предложить пользователю добавить существительное, глагол и прилагательное в текстовое поле. В этих быстрых сообщениях будет переменная с количеством вопросов, на которые пользователь должен ответить. Таким образом, после каждого запроса они успешно ответят на следующий запрос, который будет читать на 1 вопрос меньше. Я не понимаю, почему приведенный ниже код не будет работать ...

var questions = 3;
var questionsLeft = " (" + questions + " questions left)"
var adjective = prompt('Please type an adjective' + questionsLeft);
questions -= 1;
var verb = prompt('Please type a verb' + questionsLeft);
questions -= 1;
var noun = prompt('Please type a noun' + questionsLeft);
alert('All done. Ready for the message?');
var sentence = "<h2>There once was a " + adjective;
sentence += ' programmer who wanted to use JavaScript to ' + verb;
sentence += ' the ' + noun + '.</h2>';
document.write(sentence);

Чтобы эта программа работала, вы должны указывать questionsLeft = " (" + questions + " questions left)" снова после каждого запроса ... Я подумал, просто добавив questions -= 1 после каждого запроса, что это будет работать, но я просто хочу понять, почему это так?

Конечный продукт, который работает ниже, чтобы вы могли ясно увидеть разницу ...

var questions = 3;
var questionsLeft = " (" + questions + " questions left)"
var adjective = prompt('Please type an adjective' + questionsLeft);
questions -= 1;
questionsLeft = " (" + questions + " questions left)"
var verb = prompt('Please type a verb' + questionsLeft);
questions -= 1;
questionsLeft = " (" + questions + " questions left)"
var noun = prompt('Please type a noun' + questionsLeft);
alert('All done. Ready for the message?');
var sentence = "<h2>There once was a " + adjective;
sentence += ' programmer who wanted to use JavaScript to ' + verb;
sentence += ' the ' + noun + '.</h2>';
document.write(sentence);

Ответы [ 5 ]

1 голос
/ 24 января 2020

Это потому, что при создании строки, например:

" (" + questions + " questions left)"

строка будет иметь нет зависимость от содержащейся в ней переменной.

Значение переменной подставляется во время создания строки.

Чтобы обойти это, можно отложить подстановку до тех пор, пока она действительно не понадобится (но это может вызвать повторяющиеся строки):

var questions = 3;
var adjective = prompt('Please type an adjective (' + questions + " questions left)");
questions -= 1;
var verb = prompt('Please type a verb (' + questions + " questions left)");
questions -= 1;
var noun = prompt('Please type a noun (' + questions + " questions left)");
alert('All done. Ready for the message?');
var sentence = "<h2>There once was a " + adjective;
sentence += ' programmer who wanted to use JavaScript to ' + verb;
sentence += ' the ' + noun + '.</h2>';
document.write(sentence);

Кроме того, вы можете сделать что-нибудь приятное с литералами шаблона с тегами ES6:

const templateCreator = (strings, ...indices) => (...substitutions) => strings.slice(1).reduce((acc, string, index) => acc + substitutions[indices[index]] + string, strings[0])

var questions = 3;

var templateFunction = templateCreator `Please type a${0} (${1} questions left)`

var adjective = prompt(templateFunction('n adjective', questions));
questions -= 1;
var verb = prompt(templateFunction(' verb', questions));
questions -= 1;
var noun = prompt(templateFunction(' noun', questions));
alert('All done. Ready for the message?');
var sentence = "<h2>There once was a " + adjective;
sentence += ' programmer who wanted to use JavaScript to ' + verb;
sentence += ' the ' + noun + '.</h2>';
document.write(sentence);

Используя вышеуказанное решение, вы можете использовать шаблон многократного использования в виде функции, которую можно вызывать столько раз, сколько вы хотите, с разными аргументами.

Для этого и используются литералы шаблона.

Но учтите, что мы по-прежнему передаем переменную questions в каждом вызове templateFunction.


Наконец, мы может go сделать еще один шаг и создать еще одну функцию, которая обернет templateFunction и в качестве переменной будет иметь переменную questions:

const templateCreator = (strings, ...indices) => (...substitutions) => strings.slice(1).reduce((acc, string, index) => acc + substitutions[indices[index]] + string, strings[0])

var questions = 3;

var templateFunction = wordClass => (templateCreator `Please type a${0} (${1} questions left)`)(wordClass, questions)

var adjective = prompt(templateFunction('n adjective'));
questions -= 1;
var verb = prompt(templateFunction(' verb'));
questions -= 1;
var noun = prompt(templateFunction(' noun'));
alert('All done. Ready for the message?');
var sentence = "<h2>There once was a " + adjective;
sentence += ' programmer who wanted to use JavaScript to ' + verb;
sentence += ' the ' + noun + '.</h2>';
document.write(sentence);
0 голосов
/ 24 января 2020

Вы можете немного изменить свой оригинальный код, чтобы заставить его работать. Обратите внимание, что вам на самом деле не нужен логарифм вопросов:

var questions = 3;

var adjective = prompt('Please type an adjective --' + questions + ' questions left');
questions -= 1;
var verb = prompt('Please type a verb --' + questions + ' questions left');
questions -= 1;
var noun = prompt('Please type a noun --' + questions + ' questions left');
alert('All done. Ready for the message?');
var sentence = "<h2>There once was a " + adjective;
sentence += ' programmer who wanted to use JavaScript to ' + verb;
sentence += ' the ' + noun + '.</h2>';
document.write(sentence);
0 голосов
/ 24 января 2020

Когда вы пишете это:

questionsLeft = " (" + questions + " questions left)"

Вы создаете новую строку во время выполнения этой строки. Вы не привязываете к ней переменную "questions", вы говоря, чтобы вставить текущее значение вопросов там. После выполнения этой строки значение questionsLeft - это просто одна строка, оно никогда не изменится, если и какой-либо код не изменит свое значение.

Подумайте об этом так, по аналогии: если я вам скажу Есть 5 разных цветовых коробок, и мой любимый цвет - это цвет сверху, а верхний - синий, тогда вы знаете, мой любимый цвет - синий. Если я позже переставлю прямоугольники так, чтобы красный находился сверху, мой любимый цвет, конечно, не изменился, он все еще синий, хотя теперь верхний прямоугольник красный.

Надеюсь, что аналогия имела смысл. ..

0 голосов
/ 24 января 2020

Это потому, что присвоение (например, questionsLeft = /* anything*/) оценивается только в тот момент, когда выполняется строка кода, а не снова.

questionsLeft = " (" + questions + " questions left)" приведет к тому, что код объединит несколько строк вместе, и, каков бы ни был конечный результат, ему присваивается значение questionsLeft. questions было необходимо для выполнения этого вычисления, но как только вычисление выполнено, связь между questions и questionsLeft больше не существует.

Существуют методы, позволяющие выполнить сортировку о том, о чем вы думаете, но код для них будет не таким простым, как код, который вы написали. Эта идея называется «Реактивное программирование», наиболее популярным примером которой является библиотека rx. js. Возможно, однажды мы получим такую ​​функцию, как эта, встроенную в язык (мне нравится предположение Пола Стовелла о Destiny Operator ), но ее сегодня не существует.

0 голосов
/ 24 января 2020

Когда вы делаете присвоение наподобие

var questionsLeft = " (" + questions + " questions left)";

, оно копирует значение questions в новую строку. Там нет автоматической c связи с переменной, изменение переменной не изменит то, что в строке.

Аналогично, если вы сделаете что-то вроде

var a = 1;
var b = a;
a = 2;
console.log(a, b);

Это будет протоколировать 2, 1, а не 2, 2. Переназначение a не влияет на b.

...