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

JS闭包对象共享状态异常:为何无法得到负分结果?

问题根源:闭包变量共享

你的代码中,studentHolberton是一个立即执行函数表达式(IIFE),内部的privateScore和name是整个IIFE的闭包变量——所有通过Object.create(studentHolberton)创建的实例,都会共用这两个变量。

实际执行流程:

  • Jerry的4次奖励操作将privateScore累加至4
  • Dray的操作是在4的基础上计算:+1后变为5,再减3最终得到2,所以输出Dray: 2,而非预期的-2
解决方案:生成独立实例的工厂函数

要让每个学生拥有独立的私有状态,需要把studentHolberton改成工厂函数,每次调用都会创建新的闭包环境,生成独立的私有变量:

function createStudentHolberton() {
  let privateScore = 0;
  let name = null;

  function changeScoreBy(points) {
    privateScore += points;
  }

  return {
    setName: (newName) => {
      name = newName;
    },
    rewardStudent: () => {
      changeScoreBy(1);
    },
    penalizeStudent: () => {
      changeScoreBy(-1);
    },
    getScore: () => {
      return `${name}: ${privateScore}`;
    },
  };
}

// 创建独立实例
const jerry = createStudentHolberton();
jerry.setName('Jerry');
jerry.rewardStudent();
jerry.rewardStudent();
jerry.rewardStudent();
jerry.rewardStudent();

console.log(jerry.getScore()); // Jerry: 4

const dray = createStudentHolberton();
dray.setName('Dray');
dray.rewardStudent();
dray.penalizeStudent();
dray.penalizeStudent();
dray.penalizeStudent();

console.log(dray.getScore()); // Dray: -2
替代方案:ES6类+私有字段

如果使用现代JavaScript,也可以用ES6类结合私有字段(#前缀)实现,语法更清晰:

class StudentHolberton {
  #privateScore = 0;
  #name = null;

  #changeScoreBy(points) {
    this.#privateScore += points;
  }

  setName(newName) {
    this.#name = newName;
  }

  rewardStudent() {
    this.#changeScoreBy(1);
  }

  penalizeStudent() {
    this.#changeScoreBy(-1);
  }

  getScore() {
    return `${this.#name}: ${this.#privateScore}`;
  }
}

const jerry = new StudentHolberton();
jerry.setName('Jerry');
jerry.rewardStudent();
jerry.rewardStudent();
jerry.rewardStudent();
jerry.rewardStudent();

console.log(jerry.getScore()); // Jerry: 4

const dray = new StudentHolberton();
dray.setName('Dray');
dray.rewardStudent();
dray.penalizeStudent();
dray.penalizeStudent();
dray.penalizeStudent();

console.log(dray.getScore()); // Dray: -2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:26:13