Works,但Uncaught ReferenceError:当我在控制台中键入数组时,未定义数组

时间:2015-10-06 10:57:47

标签: javascript arrays html5

我用js制作了一个Tic Tac Toe游戏,我有几个阵列。

- 一个用于html td元素(网格)
- 看看之前是否点击了它们(boolGrid)
- 用颜色检查结束条件(colorgrid)

我使用var关键字及其内容在全局范围内定义了所有这些,现在游戏确实有效,但是当我在控制台中键入它们的名称时,它给了我未捕获的ReferenceError:数组未定义。我想知道自从我尝试下一个OXO游戏后会发生什么。

以下是代码的链接,
TicTacToe:https://jsfiddle.net/NeuroTypicalCure/0k73umd1/3/
我在OXO上的进展:https://jsfiddle.net/NeuroTypicalCure/vdz5q97v/(显然未完成)

    var grid = [
    document.getElementById("a").children[0],
    document.getElementById("a").children[1],
    document.getElementById("a").children[2],
    document.getElementById("b").children[0],
    document.getElementById("b").children[1],
    document.getElementById("b").children[2],
    document.getElementById("c").children[0],
    document.getElementById("c").children[1],
    document.getElementById("c").children[2],
];
var boolGrid = [
    false,false,false,
    false,false,false,
    false,false,false
];
var colorGrid = [
    "grey","grey","grey",
    "grey","grey","grey",
    "grey","grey","grey"
];
var resetButton = document.getElementById("rb");

var color = "green";
var clicks = 0;

function allTiles(color){
    for(var i=0;i<grid.length;i++){
        grid[i].style.backgroundColor = color;
        boolGrid[i] = true;
    }
}
function init(){
    for(var i=0;i<grid.length;i++){
        grid[i].style.backgroundColor = "grey";
        boolGrid[i] = false;
        colorGrid[i] = "grey";
    }
}
function listen(arr,num){
    arr[num].addEventListener("click",function(){
            if(clicks == 0 || clicks%2 == 0){
                color = "green";
            }else{
                color = "red";
            }
            if(boolGrid[num] === false){
                arr[num].style.backgroundColor = color;
                boolGrid[num] = true;
                colorGrid[num] = color;
                clicks++;
                checkEnd("green");
                checkEnd("red");
            }
        });
}
function addEventListeners(){
    for(var i=0;i<grid.length;i++){
        listen(grid,i);
    }
}
function checkEnd(color){
    // ----------------- horizontal --------------
    if(colorGrid[0] === color && colorGrid[1] == color && colorGrid[2] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
    if(colorGrid[3] === color && colorGrid[4] == color && colorGrid[5] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
    if(colorGrid[6] === color && colorGrid[7] == color && colorGrid[8] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
    //------------ vertical --------------
    if(colorGrid[0] === color && colorGrid[3] == color && colorGrid[6] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
    if(colorGrid[1] === color && colorGrid[4] == color && colorGrid[7] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
    if(colorGrid[2] === color && colorGrid[5] == color && colorGrid[8] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
    // ------------------ diagonal -------------------
    if(colorGrid[0] === color && colorGrid[4] == color && colorGrid[8] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
    if(colorGrid[2] === color && colorGrid[4] == color && colorGrid[6] === color){
        console.log(color+"Wins!");
        allTiles(color);
    }
}
init();
addEventListeners();
resetButton.addEventListener("click",function(){
    init();
})

请事先告诉我任何提示或更正:)

祝你的项目好运,
-T

1 个答案:

答案 0 :(得分:0)

正如您所指定的,游戏运行正常,失败的是当您尝试使用控制台(在JSFiddle中)访问变量时失败。出现这种情况有两个原因:

  1. 控制台的上下文。
  2. 变量的范围。
  3. 简化一下:控制台的上下文是受控制台操作影响的文档。默认情况下,在Chrome中,上下文是顶部框架,但可以使用左上角的下拉列表进行更改:

    enter image description here

    在您的情况下,您使用的是JSFiddle,而JSFiddle使用iframe来显示结果。如果控制台的范围是&#34;&lt; top frame&gt;&#34;,那么您将无法从结果窗口访问变量。您需要将下拉菜单更改为&#34;结果(fiddle.jshell.net/)"值。

    但是,即使你这样做,你仍然会得到错误。这是为什么?因为第二个原因:变量的范围。同样简化一点,变量范围是程序中可以查看/访问变量的部分。它可以是整个应用程序(全局变量),也可以只是它的一部分(局部变量)。

    在您的情况下,您在函数中使用了var关键字(即使您不认为您在函数中使用它,实际上就像您选择的那样&#34; On加载&#34;用于JavaScript执行,并将您的代码包装在窗口加载时执行的匿名函数中),这使得该函数的所有变量都是本地的。

    当您尝试从控制台打印变量时,无法访问它们,因为它们的范围是特定功能,并且它们不存在于其外部。要解决这个问题:

    • 删除var关键字,使变量变为全局变量。建议不要使用此选项,因为它可能会产生意外结果(任何函数都可以访问该变量,调试/维护可能会成为一场噩梦);或

    • 而不是使用&#34; onLoad&#34;执行JavaScript的选项,使用&#34; No wrap-in&lt; body&gt;&#34;。这样,您的代码就不会被window.onload=function(){ }包裹,而是直接进入正文底部的<script>

    虽然从技术上讲,你正在做的是使变量成为全局变量(因为即使使用var,它们也不属于所有函数,所以任何人都可以访问它们。

    tl; dr; - 解决问题:

    1. 将控制台的上下文更改为iframe。
    2. 更改变量的范围,以便控制台可以访问它们。