[JS # 2 WIL Post]

Encapsulation is not inherent in Javascript. There are no modifiers like private and public to help protect objects from unwanted access. This is one reason why function scope is important in JS. Each function creates a new scope. The scope dictates the visibility of the variables inside a function.

For example in the snippet below, the gridItems attribute of the gameboard cannot be accessed directly unless the getter/setter method is used. Thus, the possibility of setting incorrect grid item values will be removed.

Note that the checking of row, column, diagonal winners of the game board is not accessible from the objects that will be importing it. Only the returned functions of GameBoard will be accessible outside it.

const GameBoard = (function() {
//no one can access this variable directly
    let gridItems = Array(9).fill('I');

    function resetBoard() {
        gridItems = Array(9).fill('I');
    }

    function setGridItemValue(index) {
        gridItems[index] = turn;
    }

    function getGridItems() {
        return gridItems.slice(0);
    }

    function checkWinner(board) {
        if(checkDraw(board)) {
            return "tie";
        }

        if(checkRowWin(board) || 
           checkColumnWin(board) || 
           checkDiagonalWin(board)) {
            return winner;
        }

        return null;
    }
    
    ...
    
    return {
        setGridItemValue,
        checkWinner,
        resetBoard,
        getGridItems,
    }
}());

One more important thing to note about this pattern aside from encapsulation is its use of IIFE (immediately invoked function expressions). It is run as soon as it is defined. It is sometimes called a self-executing anonymous function and has two parts: A. The function itself with the Grouping operator

(function () {
  statements
})

B. The second one creates the IIFE () through which the JS engine will directly interpret the function.

The second part makes sure that there is no accidental invocation of the function, thus creating a lot of GameBoard objects. To use the GameBoard, the user can just call the publicly available functions, i.e,

GameBoard.resetBoard();
GameBoard.checkWinner();

Now, the GameBoard module can be used in other parts of the JS projects. Check the usage of the GameBoard function in this repository.

References [1] [Revealing Module Pattern] (https://gist.github.com/zcaceres/bb0eec99c02dda6aac0e041d0d4d7bf2) [2] IIFE

This post is also available on DEV.