1

我有这个递归函数,它假设通过一个 JSON 对象来查找所有子组。这是我所拥有的:

var subgroupIds = [];
this.getSubGroups = function (groupId) {
    this.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return subgroupIds;
        } else {
            $.each(groups, function(index,group) {
            subgroupIds.push(group.id);
                this.getSubGroups(group.id);
            });
        }
    });
}

...其中 getGroups 是返回所有组的异步函数。

我的问题是当它进行递归调用时,我收到错误消息:

Uncaught TypeError: Object #<Object> has no method 'getSubGroups' 

我猜这是一个范围问题,但我无法弄清楚它有什么问题。有任何想法吗?

编辑:

正如Bergi 指出的那样,我需要回电。这就是我现在所拥有的:

var subgroupIds = [];
var that = this;
this.getSubGroups = function (groupId,callback) {
    this.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return;
        } else {
            $.each(groups, function(index,group) {
            subgroupIds.push(group.id);
                callback(group.id);
                that.getSubGroups(group.id);
            });
        }
    });
}

现在的问题是当我调用回调时,它说函数未定义。

最终,我想返回一个子 group.id 的数组。我不知道怎么去那里......

4

4 回答 4

1

这是因为定义的内部函数each不属于this您的类/对象的实例,而不是指回调函数本身。为了绕过这个问题,在对象构造函数中,我输入了以下内容:

一般解决方案:

function SimpleClass() {
     var _this = this;    //Private property, will be shared in all functions defined in the class
     this.value = "Hello";
     this.value2 = " world!";

     function say() {        //private function - use _this (this means something else here)
         return _this.say;   //Gets property of the object
     }
     this.say = function() { //Public function - use this
        alert(this.value+say());  //Here, we can use both this and _this
     }

}

修复您的代码:

var _this = this;
var subgroupIds = [];
this.getSubGroups = function (groupId) {
    this.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return subgroupIds;
        } else {
            $.each(groups, function(index,group) {
            subgroupIds.push(group.id);
                _this.getSubGroups(group.id);
            });
        }
    });
}
于 2013-02-27T21:06:45.927 回答
1

你的和以前this不一样this了。也许在您第一次调用之前保存this到一个与其引用的对象更相关的变量名(我将使用someObject...)getSubGroups,然后再调用someObject.getSubGroups

var subgroupIds = [];
var someObject = this;
someObject.getSubGroups = function (groupId) {
    this.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return subgroupIds;
        } else {
            $.each(groups, function(index,group) {
            subgroupIds.push(group.id);
                someObject.getSubGroups(group.id);
            });
        }
    });
}

发生这种情况的原因是因为您的函数是从$.each实现中调用的。我会参考“this”的 MDN 文档以获取更多详细信息。

于 2013-02-27T21:06:46.893 回答
1

内部this指的是$.each回调,你可以这样做:

var subgroupIds = [];
var self = this;
self.getSubGroups = function (groupId) {
    self.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return subgroupIds;
        } else {
            $.each(groups, function(index,group) {
            subgroupIds.push(group.id);
                self.getSubGroups(group.id);
            });
        }
    });
}
于 2013-02-27T21:06:52.820 回答
1

这是因为this在函数级别定义,并且在这种情况下绑定到您为内部函数迭代的数组中的项目。 this内部函数中的this内容与外部函数中的内容不同。您可以通过 var that = this;在外部级别设置并that从内部函数内部引用来解决此问题

var subgroupIds = [];
var that = this;
this.getSubGroups = function (groupId) {
    this.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return subgroupIds;
        } else {
            $.each(groups, function(index,group) {
            subgroupIds.push(group.id);
                that.getSubGroups(group.id);
            });
        }
    });
}

有关更多信息,请参阅闭包如何工作

在这里了解这在 JS 中的工作原理

于 2013-02-27T21:07:16.820 回答