You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript对象属性引用异常:actions中attackroll显示undefined问题

问题描述

在搭建桌面角色扮演游戏的RPG属性网站时,JavaScript对象adaptiveShimmerer的actions属性尝试引用同对象的attackroll值,但网页渲染时该位置显示为undefined。具体场景是通过Attack方法为attackroll赋值,期望actions字符串能调用该值,但未达到预期效果。

相关代码如下:

adaptiveShimmerer : {
    name: "Adaptive Shimmerer", 
    size: "Large",
    type: "Beast",
    subtype: "",
    alignment: "Unaligned",
    armorClass: "14 (Nautral Armor)",
    CalcHitPoints: 0,
    AutohitPoints: 66,
    hitDice: "6d10 + 30",
    hitDie: 10,
    hitDieNumber: 6,
    HP: function() {
        for(let i =0; i< this.hitDieNumber; i++)
        this.CalcHitPoints += ((1 + Math.floor(Math.random()*this.hitDie))+ (Math.floor(((this.con)-10)/2)))
    },
    Attack: function() {
        this.attackroll = ((this.proficiency + Math.floor(((this.str)-10)/2)).toString());
        console.log(this.attackroll)
    },
    speed: "20 ft, climb 20 ft.",
    proficiency: 2,
    str: 18,
    dex: 9,
    con: 20,
    int: 2,
    wis: 16,
    cha: 16,
    attackroll: "",
    savingThrows: "con: +7, cha: 5",
    skills: "",
    damageVulerabilites: "",
    damageResistance: "",
    damageImmunities: "",
    conditionImmunities:"",
    senses: "passive Perception 13",
    languges: "-",
    location: "Forest, Jungle",
    locationTags: {
        1: "Forest",
        2: "Jungle",
    },
    triome: "Indatha, Ketria, Zagoth",
    triomeTags : {
        1: "Indatha",
        2: "Ketria",
        3: "Zagoth"
    },
    cr: 2,
    xp: "(450 xp)",
    traits: "Shimmer. Any area within 60 feet of Adaptive Shimmerer counts as bright light. All creatures within 30 feet of Adaptive Shimmer (including itself) gain disadvantage on stealth checks. ",
    mutate: "Whenever this creature mutates, it gains +4 str and +4 con.",
    actions:"Bite. +" + this.attackroll +  " to hit, reach 5ft, one target. Hit: 16 (3d8 + 4 piercing damage).",
    legendaryActions: "",
    behaviour: "The Adaptive Shimmerer is usually the larval form of the Luminous Broodmoth, however due to Ikoria's unusual ecology it can mutate into almost any other Ikorian creature. Though quite large compared to humanoids it is quite shy, usually living in trees and eating absurd amounts of leaves. ",
    lair: "",
    imageUrl: "assets/adaptiveShimmerer.jpg",
    imageDiscription: "Giant Shiny Caturpiller",
}

HTML渲染代码:

const html12=`
<h3>Actions</h3>
<p> ${monsterManual[item1].actions}</p><br>
`

最终网页显示:Bite. +undefined to hit, reach 5ft, one target. Hit: 16 (3d8 + 4 piercing damage).

问题原因
  • 对象字面量初始化时this指向错误:在定义adaptiveShimmerer对象时,actions中的this并不指向当前正在创建的对象,而是指向当前代码的上下文(浏览器中通常是window对象,严格模式下为undefined),因此初始化时this.attackroll为undefined,导致actions字符串固定为包含undefined的静态值。
  • 静态字符串无法自动更新:即使后续调用Attack方法更新了attackroll的值,actions已经是初始化时生成的静态字符串,不会自动重新计算。
解决方案

方法1:将actions改为方法动态生成

把actions从静态字符串改为函数,每次调用时获取最新的attackroll值:

adaptiveShimmerer : {
    // ... 保留其他所有属性
    Attack: function() {
        this.attackroll = ((this.proficiency + Math.floor(((this.str)-10)/2)).toString());
        console.log(this.attackroll)
    },
    // 修改actions为方法
    actions: function() {
        return `Bite. +${this.attackroll} to hit, reach 5ft, one target. Hit: 16 (3d8 + 4 piercing damage).`;
    },
    // ... 保留其他所有属性
}

渲染时调用该方法:

const html12=`
<h3>Actions</h3>
<p> ${monsterManual[item1].actions()}</p><br>
`

方法2:调用Attack后手动更新actions

如果不想修改actions的类型,可以在调用Attack方法后,手动重新赋值actions:

// 先调用Attack更新attackroll
monsterManual[item1].Attack();
// 手动更新actions字符串
monsterManual[item1].actions = `Bite. +${monsterManual[item1].attackroll} to hit, reach 5ft, one target. Hit: 16 (3d8 + 4 piercing damage).`;

// 再执行渲染
const html12=`
<h3>Actions</h3>
<p> ${monsterManual[item1].actions}</p><br>
`

方法3:使用ES6 getter属性(推荐)

利用ES6的getter特性,让actions每次被访问时动态计算,无需手动调用方法,只要attackroll更新,actions就会自动返回最新值:

adaptiveShimmerer : {
    // ... 保留其他所有属性
    Attack: function() {
        this.attackroll = ((this.proficiency + Math.floor(((this.str)-10)/2)).toString());
        console.log(this.attackroll)
    },
    // 使用getter定义actions
    get actions() {
        return `Bite. +${this.attackroll} to hit, reach 5ft, one target. Hit: 16 (3d8 + 4 piercing damage).`;
    },
    // ... 保留其他所有属性
}

渲染时直接访问actions即可,和原来的代码一致:

const html12=`
<h3>Actions</h3>
<p> ${monsterManual[item1].actions}</p><br>
`

内容的提问来源于stack exchange,提问作者Justin Logue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 13:58:18