Philipp's answer already shows the right direction. I just think the data structure is needlessly verbose. Shorter texts would be easier to write and read.
Even if shorter texts would make the algorithm a bit more complex, that's worth doing, because you only write the algorithm once, but most of your time will be spent writing and maintaining the story. Therefore optimize for making easier the part you will spend most time doing.
var story = [
{ m: "Hi!" },
{ m: "This is my new game." },
{ question: "Do you like it?", answers: [
{ m: "yes", next: "like_yes" },
{ m: "no", next: "like_no" },
] },
{ label: "like_yes", m: "I am happy you like my game!", next: "like_end" },
{ label: "like_no", m: "You made me sad!", next: "like_end" },
{ label: "like_end" },
{ m: "OK, let's change the topic" }
];
Some explanations for this design:
The whole story is written in one array. You don't have to provide numbers, they are provided automatically by the array syntax: the first item has index 0, the next one has index 1, etc.
In most cases, it is not necessary to write the number of the following step. I assume that most lines of text are not branches. Let's make "the next step is the following item" a default assumption, and only make notes when it is otherwise.
For jumps, use labels, not numbers. Then, if you later add or remove a few lines, the logic of the story will be preserved, and you don't have to adjust the numbers.
Find a reasonable compromise between clarity and shortness. For example, I suggest to write "m" instead of "message", because that will be the most frequently used command ever, so making it short will make the text more legible. But there is no need to shorten the remaining keywords. (However, do as you wish. The important thing is to make it most legible for you. Alternatively, you could support both "m" and "message" as valid keywords.)
The algorithm for the game should be something like this:
function execute_game() {
var current_line = 0;
while (current_line < story.length) {
var current_step = story[current_line];
if (undefined !== current_step.m) {
display_message(current_step.m);
if (undefined !== current_step.next) {
current_line = find_label(current_step.next);
} else {
current_line = current_line + 1;
}
} else if (undefined !== current_step.question) {
// display the question: current_step.question
// display the answers: current_step.answers
// choose an answer
// and change current_line accordingly
}
}
}
By the way, these ideas were inspired by Ren'Py, which is not exactly what you want (not JavaScript, not web), but could give you some cool ideas anyway.