未捕获的TypeError:无法设置未定义的属性“0”

时间:2012-05-20 12:05:01

标签: javascript

我收到了错误

  

未捕获的TypeError:无法设置未定义的属性“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";
}
}

5 个答案:

答案 0 :(得分:32)

JavaScript中的数组有他们自己的怪癖,如果你来自其他语言,你可能不会期待。您的用例有两个重要的用途:

  1. 您无法在JavaScript中直接声明多维数组。
  2. 在创建时设置数组的大小时,效率很小(并且没有额外的安全性)。
  3. 与其他语言不同,JavaScript不会为完整数组分配内存块。 (它不知道你将在每个细胞中放入什么样的物体, 因此需要多少总内存。) 相反,size的所有Array()参数都为您设置了数组的length属性。

    对于一般的2d阵列情况,我建议:

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

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

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

      在英文中,上述声明如下: “如果a的第i个元素是'falsy',请为第i个元素指定一个空数组。”

    3. 最后,将实际值分配给multideminsional数组:

      a[i][j] = 'whatever'
      
    4. 对于您的情况,您提前知道价值, 所以你可以提前初始化每个元素。 (但是,如果你没有覆盖大部分元素, 懒惰的实现可能会更好;见下文。)

      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个元素的数组的索引编号从九十九, 所以这里比较不合适。


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

      我在这里使用的初始化模式称为 immediately invoked function expression。 如果你以前没见过, 它是更有用的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))
      

答案 1 :(得分:2)

这个

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

必须是:

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

答案 2 :(得分:2)

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(&lt; 100)而不是100(&lt; =)

答案 3 :(得分:0)

您正在为world_map_array[i]表达式提供i中不存在的值 world_map_array。所以我猜x_world_map_titles是&gt; 2。

我认为您需要将i<=2重写为i<=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"; 
  }
}

答案 4 :(得分:-1)

在javascript中使用二维数组时获取未捕获的TypeError。

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

var arryTwoDimension = [];

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

创建子数组

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

这将解决问题。