跨变量引用对象属性失效,求正确的属性引用语法
问题根源:变量声明顺序导致的未定义错误
嘿,这个问题其实是JavaScript变量提升搞的鬼!你看你现在的代码里,player对象定义在sword对象前面,而player.weapon直接赋值为sword——但用var声明的变量虽然会被提升到作用域顶部,可赋值操作并不会被提升。也就是说,当JavaScript执行到var player = {...}这一行时,sword还只是一个undefined,根本不是你后面定义的那个武器对象!这就导致你点击按钮后,尝试访问player.weapon.name时,本质是在访问undefined.name,自然会直接崩溃。
VSCode的提示之所以显示可行,是因为编辑器做的是静态代码分析,它能看到后面有sword的定义,但不会考虑代码的执行顺序,所以才会给你错误的提示。
解决方法:调整变量定义顺序
最简单的修复方式,就是把sword的定义放到player前面,这样当创建player对象时,sword已经是一个完整的对象了:
// 物品对象 先定义! var sword = { name: "sword", bigname: "Sword", strength: 0, accuracy: 0, type: null, }; // 玩家变量 后定义 var player = { name: "Player", health: 100, armor: 0, strength: 1, accuracy: 80, knowledge: 0, weapon: sword, // 现在sword已经存在了 }; // DOM 变量 var equipButton = document.getElementById('equip-button'); // UI 变量 var equipQuery = false; equipButton.style.display = 'none'; showStatus(); // 按钮事件处理器 equipButton.addEventListener('click', function() { equipQuery = true; showStatus(); }); // 屏幕输出函数 function showStatus() { if (equipQuery == true) { // 点击了装备按钮 textArea.innerText = "You are wielding " + player.weapon.name; equipQuery = false; // 关闭装备请求状态 equipButton.style.display = 'none'; // 设置按钮状态,允许玩家返回 return; } textArea.innerText = "Your name is " + player.name; // 默认文本 }
更优方案:使用let/const替代var
另外,建议你尽量用let或const来替代var,因为它们的作用域规则更清晰,不会出现这种容易混淆的变量提升问题。比如把所有var换成const(如果变量不需要重新赋值的话):
// 物品对象 const sword = { name: "sword", bigname: "Sword", strength: 0, accuracy: 0, type: null, }; // 玩家变量 const player = { name: "Player", health: 100, armor: 0, strength: 1, accuracy: 80, knowledge: 0, weapon: sword, }; // DOM 变量 const equipButton = document.getElementById('equip-button'); // UI 变量 let equipQuery = false; // 这个需要修改,所以用let // 后续代码不变...
这样调整后,player.weapon.name就能正常访问到sword的name属性啦!
内容的提问来源于stack exchange,提问作者bmeri
相关产品推荐
相关产品推荐

