Закрытие экземпляра Undefined

Это точно правильно, потому что компилятор должен знать, какой тип он предназначен для распределения. Поэтому классы шаблонов, функции, перечисления и т. Д. Должны быть реализованы также в файле заголовка, если он должен быть опубликован или частично из библиотеки (статический или динамический), поскольку файлы заголовков НЕ скомпилированы в отличие от файлов c / cpp, которые находятся. Если компилятор не знает, что тип не может его скомпилировать. В .Net это возможно, потому что все объекты происходят из класса Object. Это не .Net.

0
задан PositiveGuy 13 July 2018 в 17:33
поделиться

1 ответ

Я понимаю, что вы не хотите делать это с помощью классов es6 или прототипа старой школы и вместо этого используйте закрытие. Это был бы не мой выбор, но я бы сказал «почему бы и нет?». Пока вы не добавили:

Но когда я добавляю игроков, у этих игроков нет ни одного из них, потому что я изначально пытался выполнить Object.assign ({} ...

( ...)

Обратите внимание, что в верхней части моей функции у меня есть player = this;

Хорошо после того, как я сделаю player = Player (); я хочу иметь возможность работать с этот экземпляр ... и поэтому добавляет игроков в свой игровой массив. Вот что я пытаюсь сделать здесь.

Вы, кажется, смешиваете концепции здесь. Ваше решение закрытия несовместимо с используя любой тип экземпляра, на который ссылается this. Поскольку вы вызываете свою функцию Player без ключевого слова new.

Нет экземпляра. scope, уже есть ваш массив players. Просто нажмите на свой новый плеер там, и все готово.

Теперь вам, похоже, нужны объекты, содержащиеся в массиве players и объекте literal возвращенный функцией Player(), чтобы выставить одну и ту же функцию, получить доступ к тем же данным через закрытие Юр.

Это можно сделать, определив функцию, которая возвращает объект литерала, который предоставляет функции:

function PlayerInterface() {
    return {
      PlayerType,
      players,
      getPlayerById,
      addPlayer
    };
}

Функция Player() вернет такой объект. И ваши объекты newPlayer будут созданы на таком объекте:

const newPlayer = Object.assign(PlayerInterface(), {
    id: null,
    name,
    symbol,
    type: playerType,
    move: null
});
players.push(newPlayer);

Таким образом, все эти объекты выставляют одни и те же функции, все они имеют одинаковый массив players в своей области, благодаря ваше закрытие.

Полный фрагмент:

function Player() {
  let players = [];

  const PlayerType = Object.freeze({
    COMPUTER: "Computer",
    HUMAN: "Human"
  });

  function getPlayerById(playerId) {
    const players = getPlayers().filter((player) => {
      return (player.id === +playerId);
    });

    return players;
  }

  function addPlayer(name, playerType, symbol) {
    const newPlayer = Object.assign(PlayerInterface(), {
      id: null,
      name,
      symbol,
      type: playerType,
      move: null
    });

    //setPlayerMoveLogic(newPlayer);
    players.push(newPlayer);
    //setPlayerId(newPlayer);

    return newPlayer;
  }

  function PlayerInterface() {
    return {
      PlayerType,
      players,
      getPlayerById,
      addPlayer
    };
  }

  return PlayerInterface();
}

const playerObject = Player();

// adding a player through that playerObject object
const computerPlayer = playerObject.addPlayer("Computer", playerObject.PlayerType.COMPUTER, "O");


// adding a player through the newly created player, computerPlayer
computerPlayer.addPlayer("Human", computerPlayer.PlayerType.COMPUTER, "H");

// you can see that both objects share the same private data through the closure 
console.log(computerPlayer.players.length);
console.log(playerObject.players.length);

Для чего это стоит, вот как бы я сделал это со старыми школьными прототипами (переименование этой игры, чтобы избежать путаницы с реальными игроками).

function Game() {
  this.players = [];
}

Game.prototype.PlayerType = Object.freeze({
  COMPUTER: "Computer",
  HUMAN: "Human"
});

Game.prototype.getPlayerById = function(playerId){
    const players = this.getPlayers().filter((player) => {
      return (player.id === +playerId);
    });

    return players;
}
  
Game.prototype.addPlayer = function(name, playerType, symbol) {
     const newPlayer = Object.assign({}, {
      id: null,
      name,
      symbol,
      type: playerType,
      move: null
    });

    //setPlayerMoveLogic(newPlayer);
    this.players.push(newPlayer);
    //setPlayerId(newPlayer);

    return newPlayer;
  };

var game1 = new Game();
var game2 = new Game();

var comp11 = game1.addPlayer("Comp1", Game.prototype.PlayerType.COMPUTER, "O");
var hum11 = game1.addPlayer("Joe", Game.prototype.PlayerType.HUMAN, "J");

var comp21 = game2.addPlayer("Comp2", Game.prototype.PlayerType.COMPUTER, "O");
var hum21 = game2.addPlayer("Peter", Game.prototype.PlayerType.HUMAN, "P");
var hum22 = game2.addPlayer("Bob", Game.prototype.PlayerType.HUMAN, "B");

console.log(game1.players);
console.log(game2.players);

4
ответ дан Guillaume Georges 17 August 2018 в 12:22
поделиться
  • 1
    это просто выбор дизайна. Закрытие дает мне такие вещи, как скрытие данных. Я не люблю использовать классы, я ненавижу этот сахар в JS ... он пытается идти против зерна, и мне нравится все упрощать. – PositiveGuy 13 July 2018 в 17:37
  • 2
    Я понимаю выбор дизайна, пока вы не попытаетесь работать с этим «экземпляром». вы упоминаете. Либо используйте закрытие, и нет экземпляра, либо используйте класс / прототип. – Guillaume Georges 13 July 2018 в 17:39
  • 3
    @PositiveGuy: Но ваш код не прост. Тот факт, что значение, возвращаемое addPlayer, должно иметь те же свойства, что и значение, возвращаемое Player, уже запутывает. Я не могу сказать, что должен делать код. Либо ваш выбор имен плох, либо логика ошибочна (или, если не ошибочна, то просто запутывается). – Felix Kling 13 July 2018 в 17:40
  • 4
    это на самом деле довольно распространенная картина. Я знаю людей, которые используют это все время. Я не знаю лучшего имени для внешней функции, которая представляет модуль, отличный от Player – PositiveGuy 13 July 2018 в 17:46
  • 5
    @FelixKling ... Я согласен, что странно добавлять игроков в Player. – PositiveGuy 13 July 2018 в 17:49
Другие вопросы по тегам:

Похожие вопросы: