未捕获的TypeError:无法设置未定义的属性“0” [英] Uncaught TypeError: Cannot set property '0' of undefined "

查看:181
本文介绍了未捕获的TypeError:无法设置未定义的属性“0”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到错误


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

Uncaught TypeError: Cannot set property '0' of undefined

由于某种原因在这一行中

for some reason in this line

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";
}
}


推荐答案

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

Arrays in JavaScript have quirks of their own that you may not be expecting if you come from other languages. Two important ones for your use case are:


  1. 您无法在JavaScript中直接声明多维数组。

  2. 在创建时设置数组的大小几乎没有效率优势(并且没有额外的安全性)。

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

Unlike other languages, JavaScript won't allocate a block of memory for the full array. (It doesn't know what kind of objects you're going to be putting in each cell, and therefore how much total memory it will need.) Instead, all the size argument to Array() does for you is set the array's length property.

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

For the general, 2d array case, I'd suggest:


  1. 创建top数组,例如:

  1. Create the "top" array, e.g.:

var i       // the first-order index in a
  , j       // the second order index in a
  , a = []


  • 根据需要初始化数组元素。
    这称为延迟初始化
    ,在这种情况下,它只是涉及测试<在我们尝试为 a [i] [j] 分配内容之前,code> a [i] 存在
    ,例如:

  • Initialize array elements as needed. This is called lazy initialization, and, in this case, it simply involves testing that a[i] exists before we try to assign something to a[i][j], e.g.:

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

    在英语中,上述语句为:
    如果的第i个元素a 是'falsy',为第i个元素分配一个空数组。

    In English the above statement reads: "If the i-th element of a is 'falsy', assign an empty array to the i-th element."

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

    Finally, assign the actual value to the multideminsional array:

    a[i][j] = 'whatever'
    


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

    For your case, you know the values ahead of time, so you can initialize each element in advance. (If you're not overriding most of the elements, however, a lazy implementation may be better; see below.)

    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个元素的数组的索引编号从 0 ,99
    所以这里的比较结果最合适。

    As some others have said, an array with 100 elements has indexes numbered from zero to ninety-nine, so a less-than comparison is most appropriate here.

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

    For reference, here's an implementation that uses lazy initialization. I've gone with a function interface instead of directly accessing the array; it's longer and more complex, but also more complete.

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

    The initialization pattern I've used here is called an immediately invoked function expression. If you haven't seen it before, it's one of the more useful JavaScript patterns and well worth taking some time to understand.

    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)
    

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

    When I ran the above in node, the following tests printed sensible values:

    // 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))
    

    这篇关于未捕获的TypeError:无法设置未定义的属性“0”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆