首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >闭包的克隆更新原始对象

闭包的克隆更新原始对象
EN

Stack Overflow用户
提问于 2018-07-15 22:06:16
回答 1查看 65关注 0票数 0

我试图克隆板,因为每次运行minMax时,我的minMax函数都需要当前板状态的副本。

最近,我将es6 Board.js模块从一个单例(从它导出函数)转换为一个闭包(函数返回一个函数,因为我想隐藏状态,还可以利用调用函数工厂来创建董事会的新实例。

所以现在Board.js看起来是这样的:

Board.js

代码语言:javascript
复制
function Board() {
  let board = [
    ' ', ' ', ' ',
    ' ', ' ', ' ',
    ' ', ' ', ' '];

  function slotIsOpen(position){
    const open = board[position] === ' ';
    return open;
  }

  function getOpenSlots(){
    const openSlots = board.filter((slot) => {
      return slot === ' '
    });
    return openSlots;
  }

  function getBoard() {
    return board;
  }

  function isFull(board){
    const emptySlots = board.filter(slot => { return slot === ' '});
    return emptySlots.length === 0;
  }

  function addMoveToBoard(position, player){
    board.splice(+position, 1, player.marker);
  }

  const api = {
    addMoveToBoard,
    isFull,
    getBoard,
    getOpenSlots,
    slotIsOpen
  };

  return api;
}

export default Board;

我的Player.js,它接受一个Board()实例:

代码语言:javascript
复制
function Player(board, ai){

  async function move({position = -1, currentPlayer = null}){
    const minMaxBoard = Object.create(board),
      nextMove = await ai.minMax(minMaxBoard, currentPlayer)

    if(nextMove){
      const moved = Move.makeMove(nextMove.openSpaceIndex, currentPlayer, board);
      return moved;
    }
  }

  const player = {
    addPlayer
  };

  return player;
}

export default Player

正在发生的事情是:

const minMaxBoard = Object.create(board) --我创建了一个板工厂的克隆(至少我是这么想的),然后将它作为Board()的副本发送到我的minMax函数中。(请记住,board in Player(board, ai)最初是我在播放器中注入的一个param。调用者只是简单地为该param发送Board()。

我的minMax函数利用这个副本,操作它来做一些分析。该副本再次是一个副本的董事会,所以它是工作的任何当前的董事会状态,而不影响原来的董事会。

在完成minMax之后,我的makeMove被调用:const moved = Move.makeMove(nextMove.index, currentPlayer, board);

问题是,这里的board应该使用发送给Player的原始板。但我注意到,不知何故,它丢失了该引用,现在正在引用minMaxBoard。为什么?

我也尝试过const minMaxBoard = Board();而不是const minMaxBoard = Object.create(board);,但这导致了problem..which,即minMax函数最终得到了一个全新的板,即empty...which,这不是我希望发送给minMax的东西。我要一份当前发送的具有当前状态的板的副本。

更新

我已经改变了它,试图提供克隆能力,但它仍然不太工作,我仍然得到一个新的空板,每次我调用克隆:

代码语言:javascript
复制
function _Board(board) {
  function slotIsOpen(position){
    const open = board[position] === EMPTY_CELL;
    return open;
  }

  function getOpenSlots(){
    const openSlots = board.filter((slot) => {
      return slot === EMPTY_CELL
    });
    return openSlots;
  }

  function getBoard() {
    return board;
  }

  function isFull(board){
    const emptySlots = board.filter(slot => { return slot === EMPTY_CELL});
    return emptySlots.length === 0;
  }

  function addMoveToBoard(position, marker){
    board.splice(position, 1, marker);
  }

  function clone() {
    return Board(board.slice());
  }

  return {
    addMoveToBoard,
    clone,
    isFull,
    getBoard,
    getOpenSlots,
    slotIsOpen
  };
}

function Board() {
  return _Board([
    ' ', ' ', ' ',
    ' ', ' ', ' ',
    ' ', ' ', ' ']);
}

export default Board;

然后在Player.js

代码语言:javascript
复制
const minMaxBoard = board.clone();
const nextMove = await ai.minMax(minMaxBoard, currentPlayer)

但我最后还是遇到了同样的问题,即克隆每次都有一个空板,而不是board当前状态的副本,而board是发送到Player的实例Board()

我也尝试过const minMaxBoard = Board(board.getBoard().slice()),但仍然没有在新板中获得当前板数组的副本。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-15 22:17:34

Object.create并不克隆传递给它的对象,而是创建一个新对象,其内部原型是传递的对象。然后,如果您继续引用(并可能发生变异)一个恰好位于原型上的属性,那么它确实会改变原始原型。

如果希望拥有多个独立的Board副本,则每次都需要显式调用Board(),例如:

代码语言:javascript
复制
function Player(board, ai){
  async function move({position = -1, currentPlayer = null}){
    // Create an entirely new Board:
    const minMaxBoard = Board();

要复制现有板的副本,可以让Board接受要使用的board数组的参数:

代码语言:javascript
复制
const defaultBoard = [
  ' ', ' ', ' ',
  ' ', ' ', ' ',
  ' ', ' ', ' '];
function Board(board = defaultBoard) {
  // ...

// other file:

function Player(board, ai){
  async function move({position = -1, currentPlayer = null}){
    const minMaxBoard = Board(board.getBoard().slice());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51352568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档