3
\$\begingroup\$

I have been using the w3 org's JavaScript Best Practices web page's examples for coding an object literal for a game.

It is my understanding that I should use this to keep all my variables and arrays that are not associated with/inside functions. I should then use methods to access and update the values and arrays.

I wanted to make sure I was on the right track (and learning code practices) before I got too far into the code.

So, using the code listed below, I would access values as follows:

var valueSquareA = t3Game.checkSquare(a);

and

var arrSq = t3Game.getSquares();

var t3Game = (function(){

    var playerImg = "images/blankSpace.gif";
    var compImg = "images/blankSpace.gif";

    var squares = []; // For keeping track of the board.

    return{
        getImgFileName: function(playerOrComp){
            if(playerOrComp ==="player"){
                return playerImg;           
            }
            else {
                return compImg;
            }                   
        },

        setImgFileName: function(choice){
            if(choice === "X"){
                playerImg = "images/X.gif";
                compImg = "images/O.gif";
            }
            else {
                playerImg = "images/O.gif";
                compImg = "images/X.gif";
            }
        },

        setBoard: function(){
            for(i=1; i<=9; i++){
                squares[i] = "empty";
            }
            // alert(squares);
        }, 

        setSquare: function(nbr, playerOrComp){
            squares[nbr] = playerOrComp;
            // alert(squares);
        },

        checkSquare: function(nbr){
            return squares[nbr];                        
        },

        getSquares: function(){
            return squares;
        }


        } // end return

})();
\$\endgroup\$
2

1 Answer 1

3
\$\begingroup\$

You're on the right track. Now a few things before stuff gets out of hand:

Not all your functions need to be on the literal. What return {} is doing is exposing stuff in the literal as t3Game in the global scope for other code to interact with your code. If you have functions that need not be exposed, define then in the closure. It will only be accessible by code within the closure, but not outside.

var t3Game = (function(){

  function myHiddenFunctionThatNeedsNotExposed(){...}

  return {...}

})();

} // end return

If you do proper indentation, then you don't need such markers. If you use an IDE, proper indentation will allow you to collapse blocks of code as well as show indent guide lines as long as you indent properly.


An alternate way to define a global namespace is the following:

;(function(ns){

  var sameVars = []

  function theHiddenFunction(){...}

  ns.myExposedFunction = function(){...}

}(this.t3Game = this.t3Game || {});

t3Game.myExposedFunction (...);

What this does is check if t3Game already exists. If it exists, it uses the existing one, and if not, uses a new literal. This way you don't accidentally destroy an existing object of the same name in the global scope.


for(i=1; i<=9; i++){
  squares[i] = "empty";
}

Arrays zero-indexed so it's best if you start with 0. Also, 9 is very ambiguous. We don't know what 9 is. Best if you put constant values in a variable with an appropriate name.


getImgFileName: function(playerOrComp){
    if(playerOrComp ==="player"){
        return playerImg;           
    }
    else {
        return compImg;
    }                   
},

can be shortened to:

getImgFileName: function(playerOrComp){
  return playerOrComp ==="player" ? playerImg : compImg;
}

setImgFileName: function(choice){
    if(choice === "X"){
        playerImg = "images/X.gif";
        compImg = "images/O.gif";
    }
    else {
        playerImg = "images/O.gif";
        compImg = "images/X.gif";
    }
},

can be shortened to:

const X_IMAGE = "images/X.gif";
const O_IMAGE = "images/O.gif"

setImgFileName: function(choice){
  const isX = choice === "X";
  playerImg = isX ? X_IMAGE : O_IMAGE;
  compImg   = isX ? O_IMAGE : X_IMAGE;
}

Again, any constant value must be defined in a variable with a good name.


Lastly, code is for humans. Write verbose names for functions and variables so that the code is understandable.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for all the suggestions. I am studying them. Quick note: Right now I am trying to find a good naming convention. One thought I have is that good variable/function names can reduce the need for comments. Right now when I code I seem to want to avoid long names for anything. I need to be more descriptive. \$\endgroup\$
    – user109140
    Commented Jul 18, 2016 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.