未捕获的TypeError:对象#<abstractajaxreq>没有方法&#39; getAjaxResponse&#39; </abstractajaxreq>

时间:2014-08-07 20:44:13

标签: javascript ajax

我想以某种方式在我的javascript中实现一些好的OOP实践。正如您所看到的,我正在使用abstractAjaxRequest,然后给它一些定义其getAjaxResponse函数的子节点。我在底部发布了错误:self.getAjaxResponse()。有人看到我的方式错误吗?

function soapReq() {
    var ajaxRequest = new SignInAjaxReq();
    ajaxRequest.init();
    var SOAPRequest = getSOAPHead();
    var bodyArgs = getLoginAttempt();
    SOAPRequest += getSOAPBody(bodyArgs[0], bodyArgs[1], bodyArgs[2]);
    SOAPRequest += getSOAPFoot();

    var url = 'xxx'
    ajaxRequest.ajaxRequest.open('POST', url, true);
    ajaxRequest.ajaxRequest.setRequestHeader( "Content-Type","text/xml; charset=utf-8");
    ajaxRequest.ajaxRequest.send(SOAPRequest);
}    

function AbstractAjaxReq() {
    var self = this;
    this.init = function() {
        self.ajaxRequest = new XMLHttpRequest();
        self.ajaxRequest.onreadystatechange = function() {
            if(self.ajaxRequest.readyState === 4){
                self.getAjaxResponse() // error here
            }
        };
        return self.ajaxRequest;
    };
};

function SignInAjaxReq() {
    var self = this;
    this.getAjaxResponse = function() {
        var xml = self.ajaxRequest.responseXML;
        var x=xml.getElementsByTagName("signInResult");
        for (i=0;i<x.length;i++) { 
            console.log(x[i].childNodes[0].nodeValue);
        }
    };
};
SignInAjaxReq.prototype = new AbstractAjaxReq();

Uncaught TypeError: Object #<AbstractAjaxReq> has no method 'getAjaxResponse' SoapRequest.js:42
    self.ajaxRequest.onreadystatechange

1 个答案:

答案 0 :(得分:2)

你的遗产有缺陷。当您create the prototype by new AbstractReq()时,self闭包变量将指向原型对象 - 它没有getAjaxResponse方法。

修复#1:使用correct inheritance

function AbstractAjaxReq() {
    var self = this;
    this.init = function() {
        self.ajaxRequest = new XMLHttpRequest();
        self.ajaxRequest.onreadystatechange = function() {
            if(self.ajaxRequest.readyState === 4){
                self.getAjaxResponse() // no more error here
            }
        };
        return self.ajaxRequest;
    };
};

function SignInAjaxReq() {
    AbstractAjaxReq.call(this); // invoke the super constructor
    var self = this;
    this.getAjaxResponse = function() {
        var xml = self.ajaxRequest.responseXML;
        var x=xml.getElementsByTagName("signInResult");
        for (i=0;i<x.length;i++) { 
            console.log(x[i].childNodes[0].nodeValue);
        }
    };
};
SignInAjaxReq.prototype = Object.create(AbstractAjaxReq.prototype);

修复#2:通过在self函数中创建变量,将实际实例分配给init

function AbstractAjaxReq() {
    this.init = function() {
        var self = this; // here!
        self.ajaxRequest = new XMLHttpRequest();
        self.ajaxRequest.onreadystatechange = function() {
            if(self.ajaxRequest.readyState === 4){
                self.getAjaxResponse() // no more error here
            }
        };
        return self.ajaxRequest;
    };
};

另外,use the prototype!例如:

var abstractAjaxPrototype = {
    init: function() {
        var self = this; // here!
        this.ajaxRequest = new XMLHttpRequest();
        this.ajaxRequest.onreadystatechange = function() {
            if (self.ajaxRequest.readyState === 4){
                self.getAjaxResponse() // no more error here
            }
        };
        return this.ajaxRequest;
    }
};
function SignInAjaxReq() { }
SignInAjaxReq.prototype = Object.create(abstractAjaxPrototype);
SignInAjaxReq.prototype.getAjaxResponse = function() {
    var xml = this.ajaxRequest.responseXML;
    var x = xml.getElementsByTagName("signInResult");
    for (i=0; i<x.length; i++) { 
        console.log(x[i].childNodes[0].nodeValue);
    }
};

而且:不要使用init方法,请使用构造函数:

function AbstractAjaxReq() {
    var self = this; // here!
    self.ajaxRequest = new XMLHttpRequest();
    self.ajaxRequest.onreadystatechange = function() {
        if(self.ajaxRequest.readyState === 4){
            self.getAjaxResponse() // no more error here
        }
    };
};
function SignInAjaxReq() {
    AbstractAjaxReq.call(this); // invoke the super constructor
}
SignInAjaxReq.prototype = Object.create(abstractAjaxPrototype);
SignInAjaxReq.prototype.getAjaxResponse = function() {
    var xml = this.ajaxRequest.responseXML;
    var x = xml.getElementsByTagName("signInResult");
    for (i=0; i<x.length; i++) { 
        console.log(x[i].childNodes[0].nodeValue);
    }
};

// Usage:
var ajaxRequest = new SignInAjaxReq();
// no ajaxRequest.init()!