如果您有一个对象并为其设置了属性,则可以在对该对象调用的函数中访问该属性。但是,如果您调用一个函数并执行 ajax 请求,以便从 onreadystatechange 调用另一个函数,则该辅助响应函数无权访问该属性。这有点令人困惑,所以看看我在这里的意思。属性 this.name 会发生变化。
//from W3Schools website
function getXHR(){if (window.XMLHttpRequest){return new XMLHttpRequest();}if (window.ActiveXObject){return new ActiveXObject("Microsoft.XMLHTTP");}return null;}
function TestObject()
{
this.name = ""; //public
var xhr = null; //private
var response = function() //private
{
if(xhr.readyState > 3)
{
alert("B: my name is " + this.name);
}
}
this.send = function() //public
{
alert("A: my name is " + this.name);
if(xhr === null)
{
xhr = getXHR();
}
var url = "http://google.com";
xhr.onreadystatechange = response;
xhr.open("GET", url, true);
xhr.send(null);
}
}
var o = new TestObject();
o.name = "Ice Cube";
o.send();
结果是:
A: my name is IceCube
B: my name is undefined
如果响应是公开的,也会发生这种情况。如果 xhr 是公开的,也会发生这种情况。发生某些事情,导致调用的响应函数无法访问相同的参数。
最佳答案
this
在 JavaScript 中的工作方式与在其他一些语言(如 C# 或 Java)中的工作方式截然不同。函数中this
的值完全由函数调用 的方式设置,而不是函数定义 的位置。更多信息: You Must Remember 'this' .
当以“正常”方式调用函数时:
foo();
...然后在函数内,this
将始终引用全局对象(在浏览器中,全局对象是window
)。对象实例上的函数没有任何内容可以将它“绑定(bind)”到该对象。例如:
var obj = {
name: "Joe",
speak: function() {
alert("I'm " + this.name);
}
};
obj.speak(); // alerts "I'm Joe"
var f = obj.speak;
f(); // alerts "I'm " (this.name is undefined within the call)
因此,要获得使用正确“上下文”(this
值)调用的事件处理程序,您必须采取特殊步骤,如 post linked above 中所述。 .
在您的特定情况下,因为您已经定义了 closures对于您的函数,您可以轻松地使用闭包关闭的变量来处理它:
function TestObject()
{
var self;
// Set up a variable referencing `this`
self = this;
// From here on out, use it instead of `this`
self.name = ""; //public
var xhr = null; //private
var response = function() //private
{
if(xhr.readyState > 3)
{
alert("B: my name is " + self.name);
}
}
self.send = function() //public
{
alert("A: my name is " + self.name);
if(xhr === null)
{
xhr = getXHR();
}
var url = "http://google.com";
xhr.onreadystatechange = response;
xhr.open("GET", url, true);
xhr.send(null);
}
}
关于闭包的更多信息 in this article ,但基本上,这是有效的,因为 self
变量可用于 TestObject
构造函数中定义的函数。您不使用 this
,因此您不必担心确保以正确设置 this
的方式调用事件处理程序。
您可能有一些原因不想使用这些闭包(内存影响,如果您创建了很多 TestObject
,因为每个 TestObject
都有自己的 <每个函数的 strong>copy),但由于这已经是您定义对象的方式,因此使用它们实际上没有任何成本。在这种特殊情况下,我猜您不会创建数以千计的 XHR 响应程序。
关于ajax 请求返回后,Javascript 对象属性变为未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3063727/