0
const module = (function() {
    let _priv = {a:1};
    return {
        get priv() {return _priv}
    }
})();

let obj = module.priv;

obj.b = 2;

console.log(module.priv); //{a:1, b:2}

Using a factory function (or revealing module pattern in this case), how do I 'get' a private object for reference but have it be immutable?

A more practical example is for a game of tic-tac-toe:

const gameBoard = (function() {
    let _board = (new Array(9)).fill(''); //want it to be immutable from the outside
    const add = (index,mark) => {
        _board[index] = mark;
    }
    const getBoard = () => {return _board}
    
    return {add, getBoard}
})();

I want _board to only be changed by the add() method, but I also want a reference to the board's state in other places in the code. But with this current code the board is exposed and can be altered.

  • 2
    Use [`Object.freeze`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) to freeze the board? – evolutionxbox Jul 21 '22 at 15:32
  • Either `Object.freeze()` it in the first place, or hand out a copy every time `getBoard` is called. – Bergi Jul 21 '22 at 15:33
  • @Bergi What's a good way to return only a copy? – caveman418 Jul 21 '22 at 15:42
  • Return [`{..._priv}`](https://stackoverflow.com/q/728360/1048572) or [`_board.slice()`](https://stackoverflow.com/q/7486085/1048572) or something – Bergi Jul 21 '22 at 15:44

1 Answers1

0

wouldn't returning a shallow copy be enough?

so instead of

{return _board}

you could do

{return [..._board]}

so in your example that would look like this

const gameBoard = (function() {
    let _board = (new Array(9)).fill(''); //want it to be immutable from the outside
    const add = (index,mark) => {
        _board[index] = mark;
    }
    const getBoard = () => {return [..._board]}
    
    return {add, getBoard, _board}
})();

console.log(gameBoard._board)
console.log(gameBoard.getBoard())
console.log(gameBoard._board === gameBoard.getBoard())

when running the code, you'll see, that the _board and the array returned from getBoard() do not reference the same object ... so changing the array, you'll get from using getBoard() does not have any effect on your actual _board.

And once you've removed _board from the return (I added it to be able to do the comparison outside the function), I don't see a way to gain access to _board from outside the function

Lord-JulianXLII
  • 1,031
  • 1
  • 6
  • 16