我想以某种方式在我的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
答案 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()!