获取TypeError:无法设置属性' 0'尝试添加到数组时未定义

时间:2014-06-24 15:41:02

标签: javascript json web-services asp.net-web-api typescript

我正在努力学习打字稿。在这次尝试中,我试图从我创建的Web服务中获取一组数字到javascript数组中。

我有以下的Typescript类:

class GameMap2 {
    Grid: Uint8Array;
    width: number;
    height: number;

    constructor(height: number, width: number) {
        this.height = height;
        this.width = width;
        this.Grid = new Uint8Array(height * width);
    }

    generateMap() {
        alert("calling generate");
        $.ajax({
            url: "/api/Maps/" + this.width + "/" + this.height,
            async: false,
            dataType: 'json',
            success: function(data) {
                alert("Ajax success");
                for (var idx = 0; idx < data.length; idx++) {
                    this.Grid[idx] = data[idx];
                }
            }
        });

    }
}

从网络服务中,我会得到类似的结果:[1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,1,1,1,1,0,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1] 现在,当我尝试循环遍历此结果并将其放入Grid数组时,我收到错误: TypeError: Cannot set property '0' of undefined

如果我将其更改为This.Grid.Push(data[idx]);,我会收到未定义的错误。 在我看来,我的网格数组实际上并不在我的ajax回调范围内。这真的可以,或者我在这里做错了什么? 有没有其他方法可以让我的数组进入javascript数组?

2 个答案:

答案 0 :(得分:2)

事实上,这个问题是由TypeScript直接解决的。该功能称为arrow function,会像这样更改您的代码定义

class GameMap2 { 
    ...
    constructor(height: number, width: number) { ... }

    generateMap() {
        alert("calling generate");
        $.ajax({

            // instead of this
            // success: function(data) {
            // use this style, and the compiler will do the magic
            // of keeping correct "this" for us
            success: (data) => {
                alert("Ajax success");
                for (var idx = 0; idx < data.length; idx++) {
                    this.Grid[idx] = data[idx];
                }
            }
         ....

请参阅TypeScript Arrow Function Tutorial (small cite)

  

...“箭头函数表达式是函数表达式的一种紧凑形式,它省略了函数关键字并对此进行了词法作用。”基本上,箭头函数可以帮助您自动保留某个范围。如果你看一下编译器输出的代码,它只会创建一个var _this = this;它在函数内部使用。

答案 1 :(得分:1)

这是因为this已在成功回调中更改了上下文。引用this并改为使用:

generateMap() {
  alert("calling generate");
  var _this = this;
  $.ajax({
    url: "/api/Maps/" + this.width + "/" + this.height,
    async: false,
    dataType: 'json',
    success: function(data) {
      alert("Ajax success");
      for (var idx = 0; idx < data.length; idx++) {
        _this.Grid[idx] = data[idx];
      }
    }
  });
}