字符串引用的对象未显示

时间:2018-02-07 22:04:48

标签: javascript html object scope global-variables

我的意图:使用对象制作CYOA

我对Javascript很陌生并且一直试图使用this code中的this Reddit comment作为模板制作一个简单的CYOA游戏。但是,我想使用对象(其值是常量)来存储消息的各种字符串值以及每个选项指向的对象,而不是让所有对象都在数组中并且必须使用使用它们来指向它们他们在数组中的索引。我的理由是,(理论上)我可以更简单地使用" msg_001"等字符串进行组织。或" story5_28"而不是在我在数组中间插入一些新的消息时更改一堆数字。

我的问题:第一条消息不再显示

基本上,我想回到第一条消息及其答案集,但它不会。

最初的printCurrentMsg()有效(将"消息" div的内容更改为msgText的值,并循环浏览对象choices数组用于设置"选项" div中的按钮,基于currentMsg中指定的对象)和按钮'相应的onlick属性似乎有效,直到它们设置为显示msg_000

似乎无论currentMsg的值是什么,printCurrentMsg都不会显示字符串引用的对象,而不是最初的时间。此外,在脚本中的不同位置使用console.log后,我发现currentMsg未被更改,console.log(typeof)currentMsg都使用window[currentMsg] }表明前者是一个字符串,后者是一个对象。我是否无意中创建了两个单独的变量?

我试过......

  • ...使用printCurrentMessage中的参数。
  • ...在函数中使用currentMsg而不是window[currentMsg]
  • ...使用点表示法而不是括号表示法。
  • ...使用this[]代替window[]

我不确定这是否与asynchronicity有关,我是accessing object properties错误,我对scope的理解是否有缺陷,或者我是否有&#39} ; m错误地使用全局变量。我应该使用某种回调吗?

使用"虚拟" msg_000 - 使用不同名称但具有相同属性的另一个对象 - 作为权宜之计解决方案,但我仍然无法理解问题所在。将所有msg_***个对象放在一个数组中并通过索引号而不是字符串引用它们也会起作用,但我仍然犹豫是否依赖于上述单调乏味以及我仍然没有&# 39;了解为什么currentMsg的值保持不变。

为了更好地表达我的问题here is a jsfiddle with my code,我也将在下面发布。



//messages
var msg_000 = { //Starts with this one, I want to be able to go back to it
  msgName: "msg_000",
  msgText: "Sup! Choose an option!",
  choices: [
    ans_000 = {
      ansText: "Climb a hill!",
      ansGoto: "msg_001" //this works
    },
    ans_001 = {
      ansText: "Skin a cat!",
      ansGoto: "msg_002" //this works
    },
    ans_002 = {
      ansText: "Build a birdhouse!",
      ansGoto: "msg_003" //this works
    }
  ]
};
var msg_001 = {
  msgName: "msg_001",
  msgText: "You summit the great snowy peaks!",
  choices: [
    ans_000 = {
      ansText: "Talk to the Recursion Guru!",
      ansGoto: "msg_000" //this doesn't work
    }
  ]
};
var msg_002 = {
  msgName: "msg_002",
  msgText: "You suffer severe lacerations to the face!",
  choices: [
    ans_000 = {
      ansText: "Start Over",
      ansGoto: "msg_000" //this doesn't work
    }
  ]
};
var msg_003 = {
  msgText: "You build a pretty average looking birdhouse. Some grackles have moved in nonetheless, placing their various knicknacks, bedding materials, and chrono-gateways within their new abode.",
  choices: [
    ans_000 = {
      ansText: "Step through the chrono-gateway!",
      ansGoto: "msg_000" //this doesn't work
    },
    ans_001 = {
      ansText: "I think I wanna climb that mountain over there.",
      ansGoto: "msg_001" //this works
    }
  ]
}

var currentMsg = "msg_000"; //the first message is "msg_000"

printCurrentMsg = function() {
  document.getElementById("message").innerHTML =
    window[currentMsg].msgText;
  //sets the message (the div with the id of "message")
  //based on the "currentMsg" variable. "currentMsg.msgText" 
  //doesn't seem to work.
  var choices = "";
  for (var i = 0, l = window[currentMsg].choices.length; i < l; i++) {
    choices += "<p><button onclick='setMessage(" +
      window[currentMsg].choices[i].ansGoto + ")'>" +
      window[currentMsg].choices[i].ansText + "<br>Goto " +
      window[currentMsg].choices[i].ansGoto + "</button></p>";
    //make the buttons, sets the button's onclick 
    //"setMessage" function's parameter to the the value of 
    //the "ansGoto" property -> in the answers object at the 
    //i/th index of the choices property array -> in the 
    //"msg_(number)" object."
  };
  document.getElementById("choices").innerHTML = choices;
  //takes the value of the "choices" [local?] variable and puts 
  //it in the "choices" div.
};

setMessage = function(msg) {
  window[currentMsg] = msg; //I think this is the source of all 
  //my problems, it's supposed to set "currentMsg" to the value 
  //of the "msg" parameter, but when I check it with 
  //console.log(currentMsg) it hasn't been changed (i.e., still 
  //it's initial value of "msg_000") and when I use 
  //console.log(window[currentMsg]) it returns "[Object 
  //object]"; using typeof shows me that "currentMsg" is a 
  //string and "window[currentMsg]" is an object. I thought 
  //they both were the same object, am I unintentionally 
  //creating two different objects?
  printCurrentMsg(); //runs that function, seems to display the 
  //messages except the ones from object "msg_000".
};

printCurrentMsg(); //Displays the initial message and choices 
//from "msg_000", but after a new message is chosen it won't 
//display "msg_000" if it's pointed to from an "ansGoto" 
//property.
&#13;
<!DOCTYPE html>
<html>

<body>

  <div id="message"></div>
  <!-- "msgText" goes here -->
  <div id="choices"></div>
  <!-- "choices" go here -->

</body>

</html>
&#13;
&#13;
&#13;

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

setMessage()执行window[currentMsg] = msg;时,它会替换包含消息的变量的值。例如。如果当前邮件为msg_000,而您setMessage(msg_002),则相当于撰写msg_000 = msg_002;

您真正想要做的是将currentMsg的值更改为新邮件的名称。所以你应该这样做:currentMsg = msg.msgName;

您还错过了msgName中的msg_003媒体资源。

作为最佳实践,您不应该为所有这些使用全局变量。创建自己的对象messages,然后使用messages[currentMsg]

&#13;
&#13;
//messages
var msg_000 = { //Starts with this one, I want to be able to go back to it
  msgName: "msg_000",
  msgText: "Sup! Choose an option!",
  choices: [
    ans_000 = {
      ansText: "Climb a hill!",
      ansGoto: "msg_001" //this works
    },
    ans_001 = {
      ansText: "Skin a cat!",
      ansGoto: "msg_002" //this works
    },
    ans_002 = {
      ansText: "Build a birdhouse!",
      ansGoto: "msg_003" //this works
    }
  ]
};
var msg_001 = {
  msgName: "msg_001",
  msgText: "You summit the great snowy peaks!",
  choices: [
    ans_000 = {
      ansText: "Talk to the Recursion Guru!",
      ansGoto: "msg_000" //this doesn't work
    }
  ]
};
var msg_002 = {
  msgName: "msg_002",
  msgText: "You suffer severe lacerations to the face!",
  choices: [
    ans_000 = {
      ansText: "Start Over",
      ansGoto: "msg_000" //this doesn't work
    }
  ]
};
var msg_003 = {
  msgName: "msg_003",
  msgText: "You build a pretty average looking birdhouse. Some grackles have moved in nonetheless, placing their various knicknacks, bedding materials, and chrono-gateways within their new abode.",
  choices: [
    ans_000 = {
      ansText: "Step through the chrono-gateway!",
      ansGoto: "msg_000" //this doesn't work
    },
    ans_001 = {
      ansText: "I think I wanna climb that mountain over there.",
      ansGoto: "msg_001" //this works
    }
  ]
}

var currentMsg = "msg_000"; //the first message is "msg_000"

printCurrentMsg = function() {
  document.getElementById("message").innerHTML =
    window[currentMsg].msgText;
  //sets the message (the div with the id of "message")
  //based on the "currentMsg" variable. "currentMsg.msgText" 
  //doesn't seem to work.
  var choices = "";
  for (var i = 0, l = window[currentMsg].choices.length; i < l; i++) {
    choices += "<p><button onclick='setMessage(" +
      window[currentMsg].choices[i].ansGoto + ")'>" +
      window[currentMsg].choices[i].ansText + "<br>Goto " +
      window[currentMsg].choices[i].ansGoto + "</button></p>";
    //make the buttons, sets the button's onclick 
    //"setMessage" function's parameter to the the value of 
    //the "ansGoto" property -> in the answers object at the 
    //i/th index of the choices property array -> in the 
    //"msg_(number)" object."
  };
  document.getElementById("choices").innerHTML = choices;
  //takes the value of the "choices" [local?] variable and puts 
  //it in the "choices" div.
};

setMessage = function(msg) {
  currentMsg = msg.msgName;
  printCurrentMsg(); //runs that function, seems to display the 
  //messages except the ones from object "msg_000".
};

printCurrentMsg(); //Displays the initial message and choices 
//from "msg_000", but after a new message is chosen it won't 
//display "msg_000" if it's pointed to from an "ansGoto" 
//property.
&#13;
<!DOCTYPE html>
<html>

<body>

  <div id="message"></div>
  <!-- "msgText" goes here -->
  <div id="choices"></div>
  <!-- "choices" go here -->

</body>

</html>
&#13;
&#13;
&#13;