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

JS中传入子函数的引用类型参数在父函数被意外修改问题咨询

问题原因

JavaScript的变量传递遵循以下规则:

  • 基础类型(数字、字符串、布尔值、null、undefined、Symbol)为值传递,函数内部修改参数不会影响外部原值
  • 引用类型(对象、数组、函数等)传递的是内存地址的拷贝,函数内部拿到的参数和外部原变量指向同一块内存空间,只要直接修改该地址指向的实体内容,就会同步影响外部的原变量,和变量是否为全局变量没有关联。

你的代码中state是二维数组,属于引用类型,transitionState函数里直接对state[individual.pairIndex][individual.index]做赋值修改,本质是直接修改了原内存地址里的内容,因此外部的state会被同步修改。

解决方法

要避免原对象被修改,核心是做深拷贝,在修改前先创建一个和原内容完全一致、但内存地址独立的新对象,所有修改都在新对象上进行:

方法1:针对二维数组场景分层拷贝

你的state是两层数组,可在validateTransition中先对state做分层拷贝,后续所有校验逻辑都基于拷贝后的对象操作:

function validateTransition(boatShore, boat, state) {
    // 先拷贝state,所有修改都在拷贝后的对象上做
    const copiedState = state.map(item => [...item])
    if (boat.length > 2 || boat.length < 1) { return false }
    for (let individual of boat) {
        if (boatShore !== copiedState[individual.pairIndex][individual.index]) return false;   
    }
    const newState = transitionState(boat, copiedState)
    for (let pair of newState) {
        if (pair[0] !== pair[1]) {
            for (let pairCheck of newState) {
                if (pairCheck[0] === pair[1]) {
                    return false;
                }
            }
        }
    }
    return true;
}

方法2:通用深拷贝方案

如果数据结构更复杂,可以用structuredClone全局方法做深拷贝,简单场景也可用JSON序列化反序列化的方式(仅支持处理JSON兼容的普通数据类型,不可处理函数、Symbol、循环引用等场景):

// structuredClone方案,兼容现代浏览器和Node.js 17+版本
const copiedState = structuredClone(state)

// 序列化方案,简单场景可直接使用
const copiedState = JSON.parse(JSON.stringify(state))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 17:24:03