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

JavaScript工厂函数sink方法无法修改sunk属性问题求助

问题根因
  • 基础类型和引用类型的赋值逻辑差异导致了这个现象:
    1. 你的工厂函数内部的sunk是布尔值,属于基础类型,return对象时是直接把sunk的当前值(初始为false)拷贝给返回对象的sunk属性,闭包内的局部变量sunk和返回对象的sunk属性后续是完全独立的两个值,没有关联。你调用sink()修改的只是闭包里的局部变量,不会同步到返回对象的属性上。
    2. 而hits是数组,属于引用类型,return时拷贝的是内存地址,闭包内的hits和返回对象的hits指向同一个数组实例,所以hit()修改数组内容时,外部读取能看到变化。
    3. 额外注意你原代码的hit方法边界判断有漏洞:position <= hits.length会允许索引等于数组长度,而数组索引最大为length-1,会出现越界赋值问题。
修复方案

方案1:为sunk属性添加getter(最常用,保留闭包私有特性)

每次读取sunk属性时,直接返回闭包里最新的局部变量值:

const Ship = (name, length, orientation = 'horizontal') => {
  let sunk = false;
  const hits = Array(length).fill(false);

  const hit = (position) => {
    // 修复边界判断
    if (position < hits.length) hits[position] = true;
  };

  function sink() {
    sunk = true;
  }

  return {
    name,
    length,
    orientation,
    // 定义getter,每次读取都返回闭包内的最新值
    get sunk() {
      return sunk
    },
    hits,
    hit,
    sink,
  };
};

方案2:直接修改实例自身属性

放弃用闭包私有变量存sunk,直接在方法内修改实例对象的属性:

const Ship = (name, length, orientation = 'horizontal') => {
  const hits = Array(length).fill(false);

  const hit = (position) => {
    if (position < hits.length) hits[position] = true;
  };

  const ship = {
    name,
    length,
    orientation,
    sunk: false,
    hits,
    hit,
    sink() {
      this.sunk = true;
    }
  };

  return ship;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:15:02