将数组中对象类型元素设为null会修改原对象还是仅修改数组索引?
国际象棋引擎赋值逻辑问题解答
核心问题答复
- 把board源格设为null仅修改board矩阵本身,不会改动
this.pieces中存储的棋子对象:JavaScript中对象属于引用类型,初始化时
this.pieces存储的是棋子类实例的引用,board矩阵每个格子存储的也是对应棋子实例的引用。将board某格赋值为null,只是切断了这个格子和棋子实例的引用关联,既不会修改this.pieces里的引用,也不会改动棋子实例本身的数据。 - 可以通过矩阵访问到原棋子对象:只要没有主动修改棋子实例自身的属性(比如
position字段),不管是从this.pieces通过键名访问,还是从board的目标格中读取引用,拿到的都是原始的棋子实例。
现有代码的隐藏问题提醒
你当前imagineMove函数中的状态保存逻辑存在漏洞:
// 现有写法只复制了引用,修改board时savedPosition会同步变化 this.savedPosition = this.board;
this.board本身是数组,直接赋值只是让savedPosition指向同一个数组实例,你后续修改board的格子内容时,savedPosition也会同步更新,根本无法实现回滚到推演前状态的需求。
你可以修改为轻量的数组拷贝实现状态保存,8x8的棋盘开销极低完全符合你的性能要求:
imagineMove(move) { // 仅拷贝每层数组,保留棋子引用,开销极低 this.savedPosition = this.board.map(row => [...row]); this.board[move.target[0]][move.target[1]] = this.board[move.source[0]][move.source[1]]; this.board[move.source[0]][move.source[1]] = null; this.switchTurns(); } // 恢复状态时使用如下代码即可 restorePosition() { this.board = this.savedPosition.map(row => [...row]); // 同步恢复回合状态 this.switchTurns(); }
额外注意事项
如果你推演走棋时会修改棋子实例自带的position属性,那推演结束恢复状态时,需要同步把对应棋子的position改回原始值,否则会修改原始数据。如果推演过程中仅改动board矩阵的引用指向,完全不会破坏原始棋子数据。
内容的提问来源于stack exchange,提问作者Giovanni Kane
相关产品推荐
相关产品推荐

