Javascript对象方法问题

时间:2012-01-28 18:28:46

标签: javascript jquery

我试图创建一个名为List的对象。该对象有一个方法add,它只是将一个任务对象推送到这个tasks数组上。我还构建了一个加载方法来从URL加载项目。

我的问题是我似乎无法在load方法中引用add方法,我收到以下错误:

未捕获的TypeError:对象#没有方法'添加'。

如何在load方法中引用add方法?我正在使用的代码如下。

function List(){
    this.tasks = new Array();
    this.add = function(taskItem){
        this.tasks.push(taskItem);
    };
    this.load = function(url){
        $.getJSON(
            url,
            function(data){
                $.each(data, function(key,val){
                    var task = new Task({
                        id:val.pkTaskId,
                        title:val.fldName,
                        status:val.fldStatus
                    });
                    this.add(task);
                });
            }
            );
    }
}

var userList = new List();
userList.load(url)

4 个答案:

答案 0 :(得分:3)

试试这个:

function List(){
    this.tasks = [];  // prefer [] over new Array()
    this.add = function(taskItem){
        this.tasks.push(taskItem);
    };
    this.load = function(url){
        var self = this;
        $.getJSON(
            url,
            function (data){
                $.each(data, function(key,val){
                    var task = new Task({
                        id:val.pkTaskId,
                        title:val.fldName,
                        status:val.fldStatus
                    });
                    self.add(task);
                });
            }
        );
    }
}

问题是this不是您认为的Ajax回调中的内容。回调函数不在对象的上下文中调用,它在全局上下文中调用(因此this将指向window对象)。

需要预先保存对象引用(按照约定self)。


this并不总是指向一个函数“属于”的对象实例。实际上,函数不像其他语言那样属于对象。 this维护 context 一个函数被调用。任何函数都可以在任何上下文中调用:

function A() {
  this.val = "foo";
  this.say = function () { alert( "A: " + this.val ); };
}

function B() {
  this.val = "bar";
  this.say = function () { alert( "B: " + this.val ); };
}

function test() { alert( "T: " + this.val ); }

var a = new A(), b = new B();

a.say()         // alerts "A: foo"
b.say()         // alerts "B: bar"
b.say.call(a);  // alerts "B: foo";      (.call() switches the context)
test()          // alerts "T: undefined" (val does not exist in window)
test.call(b)    // alerts "T: bar"       (Ah!)

除非您隐式定义上下文(b.say()暗示thisb)或明确定义(使用call()apply()),否则上下文将是全局上下文 - 在浏览器中是window对象。这就是你的Ajax回调的情况。

答案 1 :(得分:3)

jQuery Ajax回调的上下文是一个对象,表示用于发出Ajax请求的选项。也就是说,传递给$.ajax(options)的调用的选项对象与$.ajaxSettings合并。您可以通过设置context选项来覆盖上下文。这意味着调用$.ajax()而不是$.getJSON()

$.ajax({
    context: this,
    url: url,
    dataType: 'json',
    success: callback
});

答案 2 :(得分:0)

使用以下语法:

function List() {
    this.tasks = new Array();
}

List.prototype.add = function(taskItem) {
    this.tasks.push(taskItem);
}

var list = new List();
list.add(…);

另外,尽量提高你的接受率,人们会更愿意帮助你。

答案 3 :(得分:0)

为了建立Tomalak的答案,你可以移动" self"到主要对象级别。事实证明,在嵌套对象函数中使用它时非常有用。

function List(){
   var self = this;
   self.tasks = new Array();
   self.add = function(taskItem){
      self.tasks.push(taskItem);
   };
   self.load = function(url){
      $.getJSON(
        url,
        function(data){
            $.each(data, function(key,val){
                var task = new Task({
                    id:val.pkTaskId,
                    title:val.fldName,
                    status:val.fldStatus
                });
                self.add(task);
            });
        });
    }
}

var userList = new List();
userList.load(url);