xmlhttprequest javascript 中 "this" 范围的双重问题
Double issue with "this" scope in xmlhttprequest javascript
我的 javascript 代码中的 this
范围有两个大问题。
创建 setAJAXGet
对象后,回调函数丢失,无法正确调用。因此,我没有调用 this.funct
,而是设置了 ajax.parent = this
;并致电 this.parent.funct
- 工作正常。
function setAJAXGet() {
this.askServer = function() {
var ajax = new XMLHttpRequest();
ajax.parent = this;
ajax.contentType = "charset:utf-8";
ajax.onreadystatechange = function() {
if (ajax.readyState==4 && ajax.status==200) {
this.parent.funct(ajax.responseText);
}
}
ajax.open( "GET", this.url+'?'+this.vars, true );
ajax.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
if (navigator.onLine) ajax.send( null ); else this.functError();
}
this.functError;
this.funct;
this.vars;
this.url;
}
当我尝试从另一个对象调用 setAJAXGet()
并且回调函数在该对象内部时,事情变得有点复杂。回调函数被正确调用,但对象中的所有其他函数(来自回调函数)都变得不可见。
function someObject() {
this.asyncGet = function() {
var get = new setAJAXGet();
//do some config here...
get.funct = this.processAsyncData;
get.askServer();
}
this.someOtherFunction = function() {
}
this.processAsyncData = function(ajaxText) {
// ajaxText is OK
this.someOtherFunction();
// this.someOtherFunction is not defined (how so?)
}
this.asyncGet();
}
我可以通过修改 setAJAXGet()
作为参数将对象传递给 processAsyncData
来解决这个问题,但它看起来很难看。
function someObject() {
this.asyncGet = function() {
var get = new modifiedSetAJAXGet();
//do config here...
get.object = this; // stores 'this' and sends it to callback as argument
get.funct = this.processAsyncData;
get.askServer();
}
this.someOtherFunction = function() {
}
this.processAsyncData = function(object, ajaxText) {
// ajaxText is OK
object.someOtherFunction();
// object.someOtherFunction works just fine
}
this.asyncGet();
}
我相信你知道更优雅的解决方案。
很难理解你的代码的 objective,但是你在 Javascript 中需要学习的主要内容是函数中 this
的值由函数是如何被调用的。这在 Javascript 中令人困惑,直到您完全理解重要的是函数的调用方式。事物如何声明并不重要,重要的是它们如何被调用。
当你做这样的事情时:
get.funct = this.processAsyncData;
放入 get.funct
的是指向 processAsyncData
方法的指针。与 get.funct
中的 this
值完全没有任何联系。所以,当你稍后调用 get.funct()
时,它与调用 this. processAsyncData()
是不一样的。 this
的值将丢失。
这就是 .bind()
派上用场的地方。您可以阅读有关 .bind here 的内容。它所做的是创建一个临时函数存根,重新附加 this
的值,以便不会发生上述分离。所以,你可以这样使用它:
get.funct = this.processAsyncData.bind(this);
然后,当您调用 get.funct()
时,它会生成与 this.processAsyncData()
完全相同的函数调用和 this
的值,因为 .bind()
已经创建了一个函数存根以自动重新附加 this
.
的所需值
正如我在之前的评论中发表的那样,在另一个答案中很好地总结了如何控制 this
的值:When you pass 'this' as an argument.
请注意,我提出的解决方案与您在评论中提到的不同。我建议您在此过程中尽早解决问题,这样 .funct
方法就可以随时被任何人调用,而无需执行任何特殊操作。
我的 javascript 代码中的 this
范围有两个大问题。
创建 setAJAXGet
对象后,回调函数丢失,无法正确调用。因此,我没有调用 this.funct
,而是设置了 ajax.parent = this
;并致电 this.parent.funct
- 工作正常。
function setAJAXGet() {
this.askServer = function() {
var ajax = new XMLHttpRequest();
ajax.parent = this;
ajax.contentType = "charset:utf-8";
ajax.onreadystatechange = function() {
if (ajax.readyState==4 && ajax.status==200) {
this.parent.funct(ajax.responseText);
}
}
ajax.open( "GET", this.url+'?'+this.vars, true );
ajax.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
if (navigator.onLine) ajax.send( null ); else this.functError();
}
this.functError;
this.funct;
this.vars;
this.url;
}
当我尝试从另一个对象调用 setAJAXGet()
并且回调函数在该对象内部时,事情变得有点复杂。回调函数被正确调用,但对象中的所有其他函数(来自回调函数)都变得不可见。
function someObject() {
this.asyncGet = function() {
var get = new setAJAXGet();
//do some config here...
get.funct = this.processAsyncData;
get.askServer();
}
this.someOtherFunction = function() {
}
this.processAsyncData = function(ajaxText) {
// ajaxText is OK
this.someOtherFunction();
// this.someOtherFunction is not defined (how so?)
}
this.asyncGet();
}
我可以通过修改 setAJAXGet()
作为参数将对象传递给 processAsyncData
来解决这个问题,但它看起来很难看。
function someObject() {
this.asyncGet = function() {
var get = new modifiedSetAJAXGet();
//do config here...
get.object = this; // stores 'this' and sends it to callback as argument
get.funct = this.processAsyncData;
get.askServer();
}
this.someOtherFunction = function() {
}
this.processAsyncData = function(object, ajaxText) {
// ajaxText is OK
object.someOtherFunction();
// object.someOtherFunction works just fine
}
this.asyncGet();
}
我相信你知道更优雅的解决方案。
很难理解你的代码的 objective,但是你在 Javascript 中需要学习的主要内容是函数中 this
的值由函数是如何被调用的。这在 Javascript 中令人困惑,直到您完全理解重要的是函数的调用方式。事物如何声明并不重要,重要的是它们如何被调用。
当你做这样的事情时:
get.funct = this.processAsyncData;
放入 get.funct
的是指向 processAsyncData
方法的指针。与 get.funct
中的 this
值完全没有任何联系。所以,当你稍后调用 get.funct()
时,它与调用 this. processAsyncData()
是不一样的。 this
的值将丢失。
这就是 .bind()
派上用场的地方。您可以阅读有关 .bind here 的内容。它所做的是创建一个临时函数存根,重新附加 this
的值,以便不会发生上述分离。所以,你可以这样使用它:
get.funct = this.processAsyncData.bind(this);
然后,当您调用 get.funct()
时,它会生成与 this.processAsyncData()
完全相同的函数调用和 this
的值,因为 .bind()
已经创建了一个函数存根以自动重新附加 this
.
正如我在之前的评论中发表的那样,在另一个答案中很好地总结了如何控制 this
的值:When you pass 'this' as an argument.
请注意,我提出的解决方案与您在评论中提到的不同。我建议您在此过程中尽早解决问题,这样 .funct
方法就可以随时被任何人调用,而无需执行任何特殊操作。