JavaScript新手求助:基于对象构建CYOA游戏及对象未显示问题
解决CYOA游戏中对象引用未定义的问题
嘿,兄弟,我懂你现在的困扰——作为JS新手,想通过常量对象来存CYOA的剧情文本和选项跳转,结果碰到了“string所引用的对象未被显示”(本质是对象未定义的报错),而且不想用数组索引的方式,对吧?这问题在新手用对象互相引用的时候太常见了,咱们一步步捋清楚怎么解决。
为什么会出现这个错误?
大概率是你在定义对象的时候,提前引用了还没声明的对象。举个典型的错误例子:
// 先定义start节点,里面引用了leftPath,但leftPath还没声明 const start = { text: "你站在一个岔路口", options: [ { text: "走左边", next: leftPath } ] }; // 后面才定义leftPath const leftPath = { text: "你走进了一片森林", options: [] };
JS是从上到下执行的,当解析start对象的时候,leftPath还没被创建,自然就会报引用的对象未定义的错误。
三种可行的解决方案
1. 先声明所有对象,再填充属性
const声明的对象虽然不能被重新赋值,但它的属性是可以修改的。所以我们可以先把所有剧情节点的对象都声明出来,再逐个填充内容和选项:
// 先声明所有节点对象,暂时为空 const start = {}; const leftPath = {}; const rightPath = {}; const treasureRoom = {}; // 填充start节点 start.text = "你站在一个岔路口,面前有两条路"; start.options = [ { text: "踏上左边的林间小路", next: leftPath }, { text: "走向右边的河边大道", next: rightPath } ]; // 填充leftPath节点 leftPath.text = "你走进森林,发现了一个锈迹斑斑的宝箱"; leftPath.options = [ { text: "打开宝箱", next: treasureRoom }, { text: "原路返回岔路口", next: start } ]; // 其他节点同理...
这种方式完全避开了提前引用的问题,所有对象都先存在了,之后再赋值属性的时候就不会出错。
2. 用函数延迟获取下一个节点
如果不想拆分对象的声明和赋值,可以用函数来延迟引用的解析——函数只有在被调用的时候才会执行,这时候后面的对象已经被声明了:
const start = { text: "你站在一个岔路口", options: [ { text: "走左边", next: () => leftPath // 用箭头函数返回目标对象 } ] }; const leftPath = { text: "你走进森林,听到了奇怪的声响", options: [ { text: "赶紧跑回岔路口", next: () => start } ] }; // 注意:获取下一个节点的时候要执行函数,比如: // const nextNode = selectedOption.next();
这种方式能保持每个节点对象的完整性,写起来更连贯,只是在跳转的时候要记得调用next()函数。
3. 用统一对象存储节点,通过键名引用
把所有节点都放在一个大对象里,用字符串键名来指定跳转目标,这样完全不用在意声明顺序,只要键名对应就行:
const storyNodes = { start: { text: "你站在一个神秘的入口前", options: [ { text: "进入洞穴", next: "cave" }, { text: "沿着山路往上走", next: "mountainPath" } ] }, cave: { text: "洞穴里很黑,你看到远处有微光", options: [ { text: "朝着微光走去", next: "treasureChamber" }, { text: "退出洞穴", next: "start" } ] }, mountainPath: { text: "山顶有一座古老的寺庙", options: [] }, treasureChamber: { text: "你找到了传说中的宝藏!游戏结束", options: [] } }; // 获取下一个节点的时候,用storyNodes[selectedOption.next]来访问
这种方式扩展性很强,后面加新节点直接往storyNodes里加就行,还能方便地遍历所有节点,适合剧情比较复杂的情况。
总结
这三种方法都能解决你的对象引用问题,选哪种全看你的习惯。如果还是搞不定,可以把你的代码片段贴出来,我帮你揪出具体的问题点~
内容的提问来源于stack exchange,提问作者innerHTML
相关产品推荐
相关产品推荐

