在JavaScript中能否使用getter追溯性地应用值?附玩家对象场景
使用Getter动态计算Benefits升级的金钱乘数效果
我有如下player对象:
var player = { moneyRatio: 3, //数值对应的金钱乘数 globalMultiplier: 1.000 //全局乘数,作用于所有产出 };我有一个名为Benefits的升级项,要求每拥有一座gradStudent建筑,就将player.moneyRatio减少0.002,其定义如下:
{ name: "Benefits", desc: "你的研究生看起来更专业,为金钱增长带来加成。", moneyCost: 200, scienceCost: null, popularityCost: null... }请问在JavaScript中能否使用getter来追溯性地应用该值?
当然可以!用Getter来实现这个需求简直是完美选择——它能让你动态实时计算生效的moneyRatio,不管你的研究生建筑数量什么时候变化、Benefits升级什么时候解锁,每次访问player.moneyRatio都会自动算出当前的正确值,完全不需要手动去“追溯”修改历史状态。
具体实现步骤
核心思路是:把原来的固定moneyRatio改成基础值存储,然后用Getter封装计算逻辑,每次访问时自动应用Benefits的效果。
1. 改造Player对象
我们需要新增几个状态变量(研究生数量、Benefits解锁标记),并把原moneyRatio替换成Getter:
var player = { // 存储原始的基础金钱乘数,避免Getter递归调用 _baseMoneyRatio: 3, globalMultiplier: 1.000, // 新增:当前拥有的gradStudent建筑数量 gradStudentCount: 0, // 新增:记录升级是否解锁 upgrades: { benefitsUnlocked: false }, // 定义Getter,动态计算实际生效的moneyRatio get moneyRatio() { let effectiveRatio = this._baseMoneyRatio; // 如果Benefits已解锁,应用每座研究生建筑减0.002的效果 if (this.upgrades.benefitsUnlocked) { effectiveRatio -= this.gradStudentCount * 0.002; // 可选:给乘数加个下限,防止变成负数破坏游戏逻辑 effectiveRatio = Math.max(effectiveRatio, 0); } return effectiveRatio; }, // 可选:如果需要修改基础乘数(比如其他升级直接调整基础值),配套Setter set moneyRatio(newBaseValue) { this._baseMoneyRatio = newBaseValue; } };
2. 如何使用
- 当玩家解锁Benefits升级时,只需要设置
player.upgrades.benefitsUnlocked = true,之后访问player.moneyRatio就会自动应用效果。 - 当玩家新增/减少gradStudent建筑时,更新
player.gradStudentCount,下次访问moneyRatio会自动同步计算结果。
比如:
// 解锁Benefits升级 player.upgrades.benefitsUnlocked = true; // 玩家建了100座gradStudent player.gradStudentCount = 100; // 此时访问moneyRatio会得到 3 - (100 * 0.002) = 2.8 console.log(player.moneyRatio); // 输出2.8
为什么这是“追溯性”的?
因为Getter不是一次性修改某个固定值,而是每次访问都基于当前所有状态重新计算。哪怕你先建了100座研究生,之后才解锁Benefits,解锁后第一次访问moneyRatio就会立刻应用所有已存在的研究生的效果——完全不需要回溯之前的操作去修改历史值,这就是你要的“追溯性”效果。
注意事项
- 一定要把原始值存在另一个变量(比如
_baseMoneyRatio)里,不要直接用moneyRatio作为存储,否则Getter会递归调用自己导致栈溢出。 - 建议给
effectiveRatio加个下限(比如Math.max(0)),防止乘数变成负数,导致金钱产出出现异常。
内容的提问来源于stack exchange,提问作者bejewelled
相关产品推荐
相关产品推荐

