Это точно правильно, потому что компилятор должен знать, какой тип он предназначен для распределения. Поэтому классы шаблонов, функции, перечисления и т. Д. Должны быть реализованы также в файле заголовка, если он должен быть опубликован или частично из библиотеки (статический или динамический), поскольку файлы заголовков НЕ скомпилированы в отличие от файлов c / cpp, которые находятся. Если компилятор не знает, что тип не может его скомпилировать. В .Net это возможно, потому что все объекты происходят из класса Object. Это не .Net.
Я понимаю, что вы не хотите делать это с помощью классов es6 или прототипа старой школы и вместо этого используйте закрытие. Это был бы не мой выбор, но я бы сказал «почему бы и нет?». Пока вы не добавили:
Но когда я добавляю игроков, у этих игроков нет ни одного из них, потому что я изначально пытался выполнить Object.assign ({} ...
( ...)
Обратите внимание, что в верхней части моей функции у меня есть player = this;
Хорошо после того, как я сделаю player = Player (); я хочу иметь возможность работать с этот экземпляр ... и поэтому добавляет игроков в свой игровой массив. Вот что я пытаюсь сделать здесь.
blockquote>Вы, кажется, смешиваете концепции здесь. Ваше решение закрытия несовместимо с используя любой тип экземпляра, на который ссылается
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);
addPlayer
, должно иметь те же свойства, что и значение, возвращаемоеPlayer
, уже запутывает. Я не могу сказать, что должен делать код. Либо ваш выбор имен плох, либо логика ошибочна (или, если не ошибочна, то просто запутывается). – Felix Kling 13 July 2018 в 17:40Player
– PositiveGuy 13 July 2018 в 17:46