【问题标题】:Uncaught TypeError: Cannot set property '0' of undefined "未捕获的类型错误:无法设置未定义的属性“0”“
【发布时间】:2012-05-27 05:51:57
【问题描述】:

我收到了错误

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

【问题讨论】:

  • 为什么会这样? 因为world_map_array[i] 在某些时候是undefined。如果数组的长度为3,则索引为012。此外,如果您从未为索引分配值,它将是 undefined
  • 我想要做的是创建一个二维数组来表示瓷砖地图。例如[0,0][1,0][2,0] [0,1][1,1][2,1] [0,2][1,1][2,2]
  • 我想你会从阅读MDN JavaScript Guide 中受益,尤其是关于数组的部分。
  • 非常感谢!!!这个链接真的很有帮助!

标签: javascript


【解决方案1】:

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

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

var arryTwoDimension= [];

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

创建子数组

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

这将解决问题。

【讨论】:

  • 请让我们知道您使用的是哪种语言,并在代码 sn-ps 周围使用反引号 ` 以便更轻松地解析您的问题。
【解决方案2】:

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

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

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

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

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

    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. 最后,将实际值赋给多维度数组:

    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, 所以这里用小于比较是最合适的。


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

我在这里使用的初始化模式称为 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))

【讨论】:

  • 非常彻底的答案,您让我意识到我的问题与原始帖子的错误有关。谢谢!!
【解决方案3】:

您正在为 world_map_array[i] 表达式提供 i 的值,该值在 world_map_array。所以我猜x_world_map_titles > 2。

我认为您需要将i&lt;=2 重写为i&lt;=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】:
    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 (

    【讨论】:

      【解决方案5】:

      这个

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

      必须是:

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

      【讨论】:

      • 不,必须是for (i=0; i &lt; x_world_map_tiles ; i++)
      • @FelixKling 请参阅下面的'for (i=0; i&lt;=x_world_map_tiles; i++)//just a test'
      • 好的,同意,它会起作用,但实际上也不正确;)
      • @FelixKling 为什么不正确?因为 OP 定义了 100,但创建了 101 个实例?
      • 是的。而且我认为这是这里的实际问题,或者至少应该让 OP 意识到这样一个事实,即从0length - 1 的数组迭代。
      猜你喜欢
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多