未捕获的类型错误 - 意外行为
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;
}
}
我正在重写康威生命游戏的实现,在重写之前我遇到了一些问题。我假设我的代码是正确的,但我对这个问题感到困惑。我对此做了一些研究,很多人都说这是由于 Chrome“做事”的方式造成的。
以下是执行时控制台中的常见输出:
gameoflife.js:54 [直播功能] 直播 细胞: 1 |死亡细胞:0 |闲置的 细胞:225 |获取单元格:0 |人数:0 gameoflife.js:54 [直播功能] 直播 细胞:2 |死亡细胞:0 |闲置的 细胞:224 |获取单元格:1 |数:1 gameoflife.js:54 [直播功能] 直播 细胞:3 |死亡细胞:0 |闲置的 细胞:221 |获取单元格:2 |数:2 gameoflife.js:54 [直播功能] 直播 细胞:4 |死亡细胞:0 |闲置的 细胞:214 |获取单元格:3 |数:3 gameoflife.js:54 [直播功能] 直播 细胞:5 |死亡细胞:0 |闲置的 细胞:206 |获取单元格:4 |数:4 gameoflife.js:54 [直播功能] 直播 细胞: 6 |死亡细胞:0 |闲置的 细胞:197 |获取单元格:5 |数:5 gameoflife.js:54 [直播功能] 直播 细胞:7 |死亡细胞:0 |闲置的 细胞:187 |获取单元格:6 |数:6 gameoflife.js:54 [直播功能] 直播 细胞:8 |死亡细胞:0 |闲置的 细胞:169 |获取单元格:7 |数:7 gameoflife.js:54 [直播功能] 直播 细胞:9 |死亡细胞:0 |闲置的 细胞:142 |获取单元格:8 |数:8 gameoflife.js:54 [直播功能] 直播 细胞:10 |死亡细胞:0 |闲置的 细胞:105 |获取单元格:9 |人数:9 gameoflife.js:64 未捕获类型错误: 无法设置属性“innerHTML” 空
所以,这里发生的是创建了 10 个活细胞,之后尝试创建一个死细胞,但相反,它返回一个错误。当我将日志记录更改为在代码之前发生时,错误之前的行是这样的:
gameoflife:62 [死亡功能] 死亡细胞: 0 |活细胞:5 |空闲单元:206 | getCell:未定义|数:5 gameoflife.js:47 未捕获类型错误:无法设置 null 属性“innerHTML”
考虑到,与创建活细胞没有区别,我不确定为什么会发生这种情况。但是,还有另一件事令人困惑,在活细胞的机会较低的情况下,创建死细胞的功能实际上起作用,然后问题是创建活细胞的功能。不仅如此,考虑到我在每次迭代时只使用一次 splice() 函数来删除 liveCells 数组或 deadCells 数组中的索引,idleCells 数组中的单元格数量存在奇怪的模式。
首先,创建网格,然后用表格单元格的ID填充idleCells。当我调用 createRandomLiveCells() 时,该函数的工作是创建随机细胞,无论是死细胞还是活细胞。因此,我希望 liveCells 数组和 deadCells 数组都构成表单元格的数量,并且idleCells 数组为空,因为没有空闲单元格,因为表单元格要么死了,要么活了。
对于未记录的代码感到抱歉,我确保它有很好的缩进和间隔以提高可读性,但希望您理解我正在尝试做的事情。
感谢您阅读这么长但希望能得到很好解释的问题以及您的帮助。
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. 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'.
Here is a common output in the console from the execution:
gameoflife.js:54 [Live function] Live
cells: 1 | Dead cells: 0 | Idle
cells: 225 | getCell: 0 | N: 0
gameoflife.js:54 [Live function] Live
cells: 2 | Dead cells: 0 | Idle
cells: 224 | getCell: 1 | N: 1
gameoflife.js:54 [Live function] Live
cells: 3 | Dead cells: 0 | Idle
cells: 221 | getCell: 2 | N: 2
gameoflife.js:54 [Live function] Live
cells: 4 | Dead cells: 0 | Idle
cells: 214 | getCell: 3 | N: 3
gameoflife.js:54 [Live function] Live
cells: 5 | Dead cells: 0 | Idle
cells: 206 | getCell: 4 | N: 4
gameoflife.js:54 [Live function] Live
cells: 6 | Dead cells: 0 | Idle
cells: 197 | getCell: 5 | N: 5
gameoflife.js:54 [Live function] Live
cells: 7 | Dead cells: 0 | Idle
cells: 187 | getCell: 6 | N: 6
gameoflife.js:54 [Live function] Live
cells: 8 | Dead cells: 0 | Idle
cells: 169 | getCell: 7 | N: 7
gameoflife.js:54 [Live function] Live
cells: 9 | Dead cells: 0 | Idle
cells: 142 | getCell: 8 | N: 8
gameoflife.js:54 [Live function] Live
cells: 10 | Dead cells: 0 | Idle
cells: 105 | getCell: 9 | N: 9
gameoflife.js:64 Uncaught TypeError:
Cannot set property 'innerHTML' of
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. When I changed the logging to happen before the code, line before the error was this:
gameoflife:62 [Dead function] Dead cells: 0 | Live cells: 5 | Idle cells: 206 | getCell: undefined | N: 5
gameoflife.js:47 Uncaught TypeError: Cannot set property 'innerHTML' of 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.
At first, the grid is created, and then idleCells is populated with IDs of table cells. When I make a call to createRandomLiveCells(), the job of that function is to create random cells either dead or alive. 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.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先
document.getElementById(str)
需要字符串,而不是您的情况中的数字。第二,html 中 ID 属性的值应遵循此处概述的规则:
http://www.w3.org/TR/html40 /struct/global.html#h-7.5.2
特别是:
请注意,ID 应从字母开始。但你使用普通数字。
First of all
document.getElementById(str)
expects string, not a number as in your case.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
In particular:
Note that ID shall start from letter. But you use plain numbers.