I created a simple minesweeper game as I am trying to get my hands dirty in JavaScript. I have tried to use the oops while doing this.I am posting 3 files:index.htmlminesweeper.jsminesweeper.cssAlso:It does not have 2 major features - timer and flagging.You may find the UI not-so-pleasing.I have hosted the game here.It would be great if I can receive some critical comments about the code in general, code structure (mainly JavaScript) and best practices I should have followed.index.html    <!DOCTYPE html><html xmlns=http://www.w3.org/1999/xhtml><head>    <meta charset=utf-8 />    <title>Minesweeper</title>    <link rel=stylesheet type=text/css href=minesweeper.css>    <script src=http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js></script>    <link href=http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css rel=stylesheet>    <script src=minesweeper.js></script></head><body>    <div id=title>MineSweeper</div>    <div id=dashboard class=controls>        <div id=help></div>        <div id=git></div>        <ul id=difficulty>            <li id=easy>Easy</li>            <li id=reg class=selected>Reg</li>            <li id=hard>Hard</li>        </ul>        <div id=feedback>            <span id=value>5</span>            <i class=fa fa-bomb></i>        </div>    </div>    <div id=board></div>    <div id=new-game class=controls>Play again?</div>    <script type=text/javascript>        var board;        $(document).ready(function () {            newGame('reg');            $('#new-game').hide();            $('#difficulty li').click(function (eventObject) {                $('#difficulty li').removeClass('selected');                $(this).addClass('selected');                var difficulty = $(this).attr('id');                newGame(difficulty);                $('#new-game').hide();            });            $('#new-game').click(function (eventObject) {                var difficulty = $('#difficulty li.selected').attr('id');                newGame(difficulty);                $('#new-game').hide();            });        });        /*            This is equivalent to-            $(function() {            });        */    </script></body></html>minesweeper.js    // Start New Gamefunction newGame(difficulty) {    // On selection of mode, create corresponding grids.    switch (difficulty) {        case 'easy':            board = new Board(6,8);            break;        case 'hard':            board = new Board(12, 15);            break;        case 'reg':        default:            board = new Board(8, 10);            break;    }    board.render();    board.gameOver = false;    $('.space').click(function (eventObject) {        board.click(eventObject.target);    });    return board;}// Board Objectfunction Board(row, col){    this.row = row;    this.col = col;       this.spaces = [];        this.gameOver = false;    this.spacesCleared = 0;    this.bombCount = 0;    this.click = function (target_elem) {        var row = $(target_elem).attr(data-row);        var col = $(target_elem).attr(data-col);        if (this.gameOver === true) {            return;        }        if (this.spaces[row - 1][col - 1].explored == true) {            return;        }        if (this.spaces[row - 1][col - 1].holds == -1) {            this.explode();        } else if (this.spaces[row - 1][col - 1].holds == 0) {            this.clear(row - 1, col - 1);            uncoverSurroundings.call(this, row - 1, col - 1);        } else {            this.clear(row - 1, col - 1);        }    }    this.render = function() {        var spaces = ;        for (i = 1; i <= row; i++) {            for (j = 1; j <= col; j++) {                spaces = spaces.concat('<div class=space data-row=' + i + ' data-col=' + j + '>&nbsp;</div>');            }            spaces = spaces.concat('<br />');        }        $('#board').empty();        $('#board').append(spaces);    }    this.explode = function() {        for (i = 0; i < this.row; i++) {            for (j = 0; j < this.col; j++) {                if (this.spaces[i][j].holds == -1) {                    var dom_target = 'div[data-row=' + (i + 1) + '][data-col=' + (j + 1) + ']';                    $(dom_target).addClass('bomb');                    $(dom_target).html('<i class=fa fa-bomb></i>');                }            }        }        this.gameOver = true;        $('#new-game').show();    }    var numBombNear = function(row, col) {        var sum = 0;        if (this.spaces[row][col].holds == -1) {            return -1;        }        sum += valueAt.call(this, row - 1, col - 1) + valueAt.call(this, row - 1, col) + valueAt.call(this, row - 1, col + 1)             + valueAt.call(this, row, col - 1) + valueAt.call(this, row, col + 1)             + valueAt.call(this, row + 1, col - 1) + valueAt.call(this, row + 1, col) + valueAt.call(this, row + 1, col + 1);        return sum;    }    function valueAt(row, col) {        if (row < 0 || row >= this.row || col < 0 || col >= this.col) {            return 0;        } else if(this.spaces[row][col].holds == -1){            return 1;        } else {            return 0;        }    }    //Initializing the Object    if (this.spaces !== undefined) {        this.spaces = new Array(this.row);        for (i = 0; i < this.row; i++) {            this.spaces[i] = new Array(this.col);            for (j = 0; j < this.col; j++) {                this.spaces[i][j] = new Space(false, 0);            }        }        var min = 1;        var max = this.row * this.col;        this.bombCount = Math.round((Math.random() * ((max / 2) - min) + (min)));        $('#value').html(this.bombCount);        for (i = 0; i < this.bombCount; i++) {            var bombIndex = Math.round(Math.random() * (max - 1));            var x = Math.floor(bombIndex / this.col);            var y = bombIndex % this.col;            this.spaces[x][y] = new Space(false, -1);        }        for (i = 0; i < this.row; i++) {            for (j = 0; j < this.col; j++) {                this.spaces[i][j].holds = numBombNear.call(this, i, j);            }        }    }    this.clear = function (row, col) {        var dom_target = 'div[data-row=' + (row + 1) + '][data-col=' + (col + 1) + ']';        $(dom_target).addClass('safe');        if (this.spaces[row][col].holds > 0) {            $(dom_target).text(this.spaces[row][col].holds);        } else {            $(dom_target).html('&nbsp');        }        checkAllCellsExplored.call(this);        this.spacesCleared++;        this.spaces[row][col].explored = true;    }    function checkAllCellsExplored(){        if (this.row * this.col - this.spacesCleared == this.bombCount) {            for (i = 0; i < this.row; i++) {                for (j = 0; j < this.col; j++) {                    if (this.spaces[i][j].holds == -1) {                        var bomb_target = 'div[data-row=' + (i + 1) + '][data-col=' + (j + 1) + ']';                        $(bomb_target).html('<i class=fa fa-smile-o></i>');                        this.gameOver = true;                        $('#new-game').show();                    }                }            }        }    }    function uncoverSurroundings(row, col) {        checkSpace.call(this, row - 1, col - 1); checkSpace.call(this, row - 1, col); checkSpace.call(this, row - 1, col + 1);        checkSpace.call(this, row, col - 1); checkSpace.call(this, row, col + 1);        checkSpace.call(this, row + 1, col - 1); checkSpace.call(this, row + 1, col); checkSpace.call(this, row + 1, col + 1);        checkAllCellsExplored.call(this);    }    function checkSpace(row, col) {        if (row < 0 || row >= this.row || col < 0 || col >= this.col || this.spaces[row][col].explored == true) {            return;        } else if (this.spaces[row][col].holds >= 0) {            this.clear(row, col);            if (this.spaces[row][col].holds == 0) {                uncoverSurroundings.call(this, row, col);                return;            }        }    }}//Space Objectfunction Space(explored, holds){    this.explored = explored;    this.holds = holds;}minesweeper.css    body {    margin: 0;    padding: 0;    border: none;    background-color: none;    color: #333;    font-family: Arial, Helvetica, sans-serif, 'Arial', sans-serif;    font-size: 16px;    text-align: center; /* Important */}/* Dashboard and Controls */#dashboard {    text-align: left;    margin-top: 30px;}.controls {    width: 438px; /* (numCols * 44) - 2 */    margin: 0 auto;    font-weight: bold;    -webkit-border-radius: 2px;    -moz-border-radius: 2px;    border-radius: 2px;    position: relative;    }#difficulty {    list-style: none;    padding: 0;    padding-left: 10px;    display: inline-block;}#difficulty li {    background-color: #bbb;    color: #fff;    cursor: pointer;    display : inline-block;    font-size: 14px;    -webkit-border-radius: 2px;    -moz-border-radius: 2px;    border-radius: 2px;    text-align: center;    padding: 6px 8px;}#difficulty li:hover { background-color: #333; }#difficulty li.selected { background-color: #777; }#board {    min-width: 440px;    margin-bottom: 50px;}.space {    background-color: #bbb;    display: inline-block;    border: 2px solid none;    margin: 2px;    cursor: pointer;    -webkit-border-radius: 2px;    -moz-border-radius: 2px;    border-radius: 2px;    width: 38px;    height: 38px;    font-size: 22px;    line-height: 38px;}.safe {    background-color: #eee;    color: #777;}.bomb {    color: #333;}.space .fa { line-height: 40px; }.space .fa-bomb { font-size: 24px; }.space .fa-smile-o { font-size: 26px; }.space:hover { background-color: #777; }#new-game {    width: 420px;    background-color: #777;    color: #fff;    font-size: 38px;    padding: 15px 0;    cursor: pointer;}#new-game:hover { background-color: #333; }#feedback {    display: inline-block;    font-size: 30px;    padding-top: 4px;    right: 0;    position:absolute;}#title {    margin-top: 10px;    font-size: 30px;    color: #777;}
Simple minesweeper game in JavaScript
javascript;jquery;html;css;minesweeper