简体   繁体   English

Uncaught TypeError-意外行为

[英]Uncaught TypeError - Unexpected behaviour

var chanceOfLiveCells = 0.5;
var gridDomReference = null;
var gridDimension = 15;
var timer = null;

function init() {

    gridDomReference = document.getElementById('grid');
    idleCells = new Array();
    liveCells = new Array();
    deadCells = new Array();

    drawGrid();
    createRandomLiveCells();

}

function drawGrid() {

    var counter = 0;
    var nodes = new Array();

    for(var x = 0; x <= gridDimension - 1; x = x + 1) {

        nodes.push('<tr>');

        for(var y = 0; y <= gridDimension - 1; y = y + 1) {

            nodes.push('<td id="' + counter + '">' + counter + '</td>');
            idleCells.push(counter);
            counter = counter + 1;

        }

        nodes.push('</tr>');

    }

    gridDomReference.innerHTML = nodes.join('');

}

function createRandomLiveCells() {

    for(var x = 0; x <= gridDimension - 1; x = x + 1) {

        for(var y = 0; y <= gridDimension - 1; y = y + 1) {

            if(Math.random() < chanceOfLiveCells) {

                liveCells.push(x * gridDimension + y);
                idleCells.splice(getCell('idle', x, y), 1);
                document.getElementById(getCell('live', x, y)).innerHTML = 'L';
                console.log('[Live function] Live cells: ' + liveCells.length + ' | ' + ' Dead cells: ' + deadCells.length
                        + ' | Idle cells: ' + idleCells.length + ' | ' + 'getCell: ' + getCell('live', x, y) 
                        + ' | N: ' + (x * gridDimension + y));

            }

            else {

                deadCells.push(x * gridDimension + y);
                idleCells.splice(getCell('idle', x, y), 1);
                document.getElementById(getCell('dead', x, y)).innerHTML = 'D';
                console.log('[Dead function] Dead cells: ' + deadCells.length + ' | ' + ' Live cells: ' + liveCells.length
                        + ' | Idle cells: ' + idleCells.length + ' | ' + 'getCell: ' + getCell('dead', x, y) 
                        + ' | N: ' + (x * gridDimension + y));

            }

        }

    }

}

function getCell(array, x, y) {

    if(x > gridDimension - 1) {

        x = 0;

    }

    if(y > gridDimension - 1) {

        y = 0;

    }

    if(x < 0) {

        x = gridDimension - 1;

    }

    if(y < 0) {

        y = gridDimension - 1;

    }

    switch(array) {

        case 'idle': 

            return idleCells[x * gridDimension + y]; 

        break;

        case 'live': 

            return liveCells[x * gridDimension + y]; 

        break;

        case 'dead': 

            return deadCells[x * gridDimension + y]; 

        break;

    }

}

I am in the process of re-writing my implementation of Conway's Game of Life, I have ran into a few issues prior to this re-write. 我正在重新编写《 Conway的人生游戏》的实现,在重新编写之前,我遇到了一些问题。 I am assuming my code is correct, but I am baffled by this issue. 我以为我的代码是正确的,但是我对此问题感到困惑。 I have done some research on it, and a lot of people are saying it is due to the way Chrome 'does things'. 我已经对此进行了一些研究,很多人说这是因为Chrome“做事”的方式。

Here is a common output in the console from the execution: 这是执行中控制台中的常见输出:

gameoflife.js:54 [Live function] Live cells: 1 | gameoflife.js:54 [实时功能]实时细胞:1 | Dead cells: 0 | 死细胞:0 | Idle cells: 225 | 闲置电池:225 | getCell: 0 | getCell:0 | N: 0 gameoflife.js:54 [Live function] Live cells: 2 | N:0 gameoflife.js:54 [实时功能]实时细胞:2 | Dead cells: 0 | 死细胞:0 | Idle cells: 224 | 空闲单元:224 | getCell: 1 | getCell:1 | N: 1 gameoflife.js:54 [Live function] Live cells: 3 | N:1 gameoflife.js:54 [实时功能]实时细胞:3 | Dead cells: 0 | 死细胞:0 | Idle cells: 221 | 闲置电池:221 | getCell: 2 | getCell:2 | N: 2 gameoflife.js:54 [Live function] Live cells: 4 | N:2 gameoflife.js:54 [实时功能]实时细胞:4 | Dead cells: 0 | 死细胞:0 | Idle cells: 214 | 闲置电池:214 | getCell: 3 | getCell:3 | N: 3 gameoflife.js:54 [Live function] Live cells: 5 | N:3 gameoflife.js:54 [实时功能]实时细胞:5 | Dead cells: 0 | 死细胞:0 | Idle cells: 206 | 闲置电池:206 | getCell: 4 | getCell:4 | N: 4 gameoflife.js:54 [Live function] Live cells: 6 | N:4 gameoflife.js:54 [实时功能]实时细胞:6 | Dead cells: 0 | 死细胞:0 | Idle cells: 197 | 闲置电池:197 | getCell: 5 | getCell:5 | N: 5 gameoflife.js:54 [Live function] Live cells: 7 | N:5 gameoflife.js:54 [实时功能]实时细胞:7 | Dead cells: 0 | 死细胞:0 | Idle cells: 187 | 闲置电池:187 | getCell: 6 | getCell:6 | N: 6 gameoflife.js:54 [Live function] Live cells: 8 | N:6 gameoflife.js:54 [实时功能]实时细胞:8 | Dead cells: 0 | 死细胞:0 | Idle cells: 169 | 空闲电池:169 | getCell: 7 | getCell:7 | N: 7 gameoflife.js:54 [Live function] Live cells: 9 | N:7 gameoflife.js:54 [实时功能]实时细胞:9 | Dead cells: 0 | 死细胞:0 | Idle cells: 142 | 闲置电池:142 | getCell: 8 | getCell:8 | N: 8 gameoflife.js:54 [Live function] Live cells: 10 | N:8 gameoflife.js:54 [实时功能]实时细胞:10 | Dead cells: 0 | 死细胞:0 | Idle cells: 105 | 闲置电池:105 | getCell: 9 | getCell:9 | N: 9 gameoflife.js:64 Uncaught TypeError: Cannot set property 'innerHTML' of null N:9 gameoflife.js:64未捕获的TypeError:无法将属性“ innerHTML”设置为null

So, what happened here is 10 live cells were created, after that a dead cell was attempted to be created, but instead, it returns an error. 因此,这里发生的是在尝试创建一个死单元之后,创建了10个活动单元,但它返回一个错误。 When I changed the logging to happen before the code, line before the error was this: 当我将日志记录更改为发生在代码之前时,错误之前的行是这样的:

gameoflife:62 [Dead function] Dead cells: 0 | gameoflife:62 [Dead function]死细胞:0 | Live cells: 5 | 活细胞:5 | Idle cells: 206 | 闲置电池:206 | getCell: undefined | getCell:未定义| N: 5 gameoflife.js:47 Uncaught TypeError: Cannot set property 'innerHTML' of null N:5 gameoflife.js:47未捕获的TypeError:无法将属性'innerHTML'设置为null

Considering, there is no difference from creating live cells I am not sure why this is happening. 考虑到创建活细胞没有什么区别,我不确定为什么会这样。 But, here is another thing that is confusing, with a lower chance of live cells, the function that creates dead cells actually works, and the problem then is the function that creates live cells. 但是,这是另一件事,令人困惑的是,活细胞的机会较低,创建死细胞的功能实际上起作用了,那么问题就在于创建活细胞的功能。 Not only that, there is a weird pattern in the number of cells in the idleCells array, considering I am only using the splice() function once at each iteration to remove an index that is either in the liveCells array or the deadCells array. 不仅如此,考虑到我在每次迭代中只使用一次splice()函数来删除liveCells数组或deadCells数组中的索引,在idleCells数组中的单元格数量上存在一个怪异的模式。

At first, the grid is created, and then idleCells is populated with IDs of table cells. 首先,创建网格,然后使用表单元格的ID填充idleCells。 When I make a call to createRandomLiveCells(), the job of that function is to create random cells either dead or alive. 当我调用createRandomLiveCells()时,该函数的作用是创建死的或活的随机单元。 So, I expect both the liveCells array and the deadCells array to make up the number of table cells and that the idleCells array is empty, since there are no idle cells because the table cells are either dead or alive. 因此,我希望liveCells数组和deadCells数组都构成表单元格的数目,并且idleCells数组为空,因为没有空闲单元格,因为表单元格是死的还是活动的。

Sorry about the undocumented code, I made sure it was nicely indented and spaced out for readability, but hopefully you understand what I am trying to do. 对未公开的代码很抱歉,我确保它已缩进并隔开一定的可读性,但希望您理解我正在尝试做的事情。

Thanks for reading this long but hopefully well-explained problem, and your help. 感谢您阅读这个冗长但希望能得到很好解释的问题,以及您的帮助。

First of all document.getElementById(str) expects string, not a number as in your case. 首先document.getElementById(str)需要字符串,而不是您所需要的数字。

And the second, value of ID attribute in html shall follow rules outlined here: http://www.w3.org/TR/html40/struct/global.html#h-7.5.2 第二,HTML中的ID属性值应遵循此处概述的规则: http : //www.w3.org/TR/html40/struct/global.html#h-7.5.2

In particular: 尤其是:

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods ("."). ID和NAME令牌必须以字母([A-Za-z])开头,然后可以跟任意数量的字母,数字([0-9]),连字符(“-”),下划线(“ _”) ,冒号(“:”)和句点(“。”)。

Note that ID shall start from letter. 请注意,ID应以字母开头。 But you use plain numbers. 但是,您使用纯数字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM