21

我收到了错误

未捕获的类型错误:无法设置未定义的属性“0”

出于某种原因在这一行

world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif";

为什么会这样?

谢谢你的帮助

var x_world_map_tiles = 100; 
var y_world_map_tiles = 100; 

var world_map_array = new Array(x_world_map_tiles);
for (i=0; i<=2; i++)//create a two dimensional array so can access the map through x and y coords map_array[0][1] etc.
{
world_map_array[i]=new Array(y_world_map_tiles);
}


for (i=0; i<=x_world_map_tiles; i++)//just a test
{
for (z=0; z<=y_world_map_tiles; z++)//just a test
{
world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif";
}
}
4

5 回答 5

46

JavaScript 中的数组有自己的怪癖,如果您来自其他语言,您可能不会想到这些怪癖。对于您的用例,两个重要的是:

  1. 您不能在 JavaScript 中直接声明多维数组。
  2. 当您在创建时设置数组的大小时,几乎没有效率优势(并且没有增加安全性)。

与其他语言不同,JavaScript 不会为整个数组分配一块内存。(它不知道您将在每个单元格中放入什么样的对象,因此不知道它需要多少总内存。)相反,为您所做的所有size参数Array()都是设置数组的length属性。

对于一般的二维数组情况,我建议:

  1. 创建“顶部”数组,例如:

    var i       // the first-order index in a
      , j       // the second order index in a
      , a = []
    
  2. 根据需要初始化数组元素。这称为延迟初始化,在这种情况下,它只涉及a[i]在我们尝试分配某些东西之前存在的测试a[i][j],例如:

    if (!a[i]) a[i] = []
    

    上面的语句用英文写成:“如果第 i 个元素a是 'falsy',则将一个空数组分配给第 i 个元素。”

  3. 最后,将实际值分配给多任务数组:

    a[i][j] = 'whatever'
    

对于您的情况,您提前知道值,因此您可以提前初始化每个元素。(但是,如果您没有覆盖大多数元素,那么惰性实现可能会更好;见下文。)

var x, x_length = 100
  , y, y_length = 100
  , map = []

// Don't be lazy
for (x = 0; x < x_length; x++) {
  map[x] = []
  for (y = 0; y < y_length; y++) {
    map[x][y] = 'grass.gif|ongrass.gif|collision.gif|above.gif'
  }
}

正如其他人所说,具有 100 个元素的数组的索引编号从099,因此在这里进行小于比较是最合适的。


作为参考,这里有一个使用延迟初始化的实现。我已经使用函数接口而不是直接访问数组;它更长、更复杂,但也更完整。

我在这里使用的初始化模式称为 立即调用函数表达式。如果您以前没有看过它,它是更有用的 JavaScript 模式之一,非常值得花一些时间来理解。

var map = (function (x_length, y_length, v_default, undefined) {
  // Unless v_default is overwritten, use ...
  v_default = v_default || 'grass.gif|ongrass.gif|collision.gif|above.gif'

  // Private backing array; will contain only values for a[x][y] 
  // that were explicitly set.
  var a = []

  // Private helper function. 
  // - Returns `true` if `x` is between `0` and `x_length - 1`
  //   and `y` is between `0` and `y_length - 1`.
  // - Returns `false` otherwise.
  function valid (x, y) {
    return (x >= 0 
      &&    x <  x_length
      &&    y >= 0
      &&    y <  y_length)
  }

  // Private helper function.
  // - Returns `true` if a[x][y] has been set().
  // - Returns `false` otherwise.
  function exists (x, y) {
    return !!a[x] && !!a[x][y]
  }

  // Private getter
  // - Returns the value of a[x][y] if it has been set().
  // - Returns `undefined` if the point (x,y) is invalid.
  // - Returns `v_default` otherwise.
  function get (x, y) {
    if (!valid(x, y))      return undefined
    else if (exists(x, y)) return a[x][y]
    else                   return v_default
  }

  // Private setter
  // - Returns the value set on success.
  // - Returns `undefined` on failure
  function set (x, y, v) {
    if (valid(x, y)) {
      // We're being lazy
      if (!a[x]) a[x] = []
      a[x][y] = v
      return a[x][y]
    }
    return undefined
  }

  // Return an interface function. 
  // - Pass the function three arguments, (x, y, v), to set a[x][y] = v
  // - Pass the function two arguments, (x, y), to get a[x][y]
  return function (x, y, v) {
    if (arguments.length > 2) {
       return set(x, y, v)
    } else {
       return get(x, y)
    }
  }
})(100, 100)

当我在节点中运行上述内容时,以下测试会打印出合理的值:

// Invalid invocations
console.log('map()                : %s', map())
console.log('map(  0)             : %s', map(0))
console.log('map( -1,   0)        : %s', map(-1,0))
console.log('map(  0,  -1)        : %s', map(0, -1))
console.log('map( -1,  -1)        : %s', map(-1, -1))

// Valid invocations
console.log('map(  0,   0)        : %s', map(0, 0))
console.log('map( 99,  99)        : %s', map(99, 99))
console.log('map(  1,   1)        : %s', map(1,1))
console.log('map(  1,   1, "foo") : %s', map(1,1, 'foo'))
console.log('map(  1,   1)        : %s', map(1,1))
于 2012-05-20T17:27:37.723 回答
3
var x_world_map_tiles = 100;
var y_world_map_tiles = 100;
var world_map_array = new Array(x_world_map_tiles);
for (i=0; i<=2; i++)//create a two dimensional array 
{
    world_map_array[i]=new Array(y_world_map_tiles);
}
for (i=0; i<x_world_map_tiles; i++)
{
    for (z=0; z<y_world_map_tiles; z++)
    {
        world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif";
    }
}

由于您的数组长度为 100,因此您必须从0( 99<100) 而不是100(<=)

于 2012-05-20T12:09:02.873 回答
2

这个

for (i=0; i<=2; i++)

一定是:

for (i=0; i<=x_world_map_tiles ; i++)
于 2012-05-20T12:08:48.643 回答
0

您正在为world_map_array[i]表达式提供一个i不存在于 world_map_array. 所以我猜x_world_map_titles是> 2。

我认为你需要重写i<=2i<=x_world_map_titles

此外,您不需要指定数组的大小。在这种情况下,我只会使用文字:

var x_world_map_tiles = 100;  
var y_world_map_tiles = 100; 

var world_map_array = [];
for (i=0; i<=x_world_map_tiles; i++)
  //create a two dimensional array of 101x101 so can access the map through x and y coords map_array[0][1] etc. { 
  world_map_array[i]=[];
}

for (i=0; i<=x_world_map_tiles; i++)//just a test { 
  for (z=0; z<=y_world_map_tiles; z++)//just a test { 
    world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif"; 
  }
}
于 2012-05-20T12:10:25.273 回答
-1

在 javascript 中使用二维数组时出现未捕获的类型错误。

对于二维数组,先声明父数组

var arryTwoDimension= [];

然后根据情况,我们可以通过

arryTwoDimension[i]=[] i 将来自 0,1,2......

这将解决问题。

于 2018-04-11T10:08:12.797 回答