function ObjectProvider() {
this.url = "ajax/inbounds.php"
this.inBounds = function () {
this.removeMarkers();
var url_string = this.url;
$.getJSON(url_string, function (data) {
for (i = 0; i != data.length; ++i) {
this.createObject(data[i]);
}
});
};
this.createObject = function (_data) {};
this.removeMarkers = function () {};
};
所以行
this.createObject( data[i] );
有一些问题,但
this.removeMarkers();
工作正常。
这两个函数都在ObjectProvider对象中定义。 尝试添加一个名为test()的函数,并且不喜欢在JSON回调函数中调用的任何内容。
答案 0 :(得分:4)
这是一个典型的范围界定问题; this
回调函数中的$.getJSON()
不再相同this
。
要解决此问题,您必须在致电this
之前保留对$.getJSON()
的引用,例如
var self = this;
$.getJSON(url_string, function(data) {
// self.createObject( data[i] );
});
或者,使用$.proxy
绑定成功回调函数:
$.getJSON(url_string, $.proxy(function(data) {
this.createObject(data[i]);
}, this));
答案 1 :(得分:0)
ajax回调中的this
位于不同的上下文中。
解决方案: 将其缓存在本地变量中。
this.inBounds = function(){
var self = this;
self.removeMarkers();
var url_string = this.url;
$.getJSON(url_string, function(data) {
for( i=0; i != data.length; ++i ){
self.createObject( data[i] );
}
});
};
答案 2 :(得分:0)
问题是,您正在将函数传递给getJSON,并且将使用“this”调用该函数,该“this”指向全局对象或jQuery定义的某个自定义对象。如果您希望回调中的“this”指向您的对象,请使用bind方法(在某些旧版浏览器中不可用,但您可以轻松找到模拟此方法的projects)。
$.getJSON(url_string, function(data) {
for( i=0; i != data.length; ++i ){
this.createObject( data[i] );
}
}.bind(this));
或定义一个辅助变量,该变量将在此回调之外指向“this”并使用其中的变量。
var self = this;
$.getJSON(url_string, function(data) {
for( i=0; i != data.length; ++i ){
self.createObject( data[i] );
}
});
答案 3 :(得分:0)
由于这个原因,我不喜欢getJSON
,与ajax
相比,它太有限了。
基本上,当success
函数执行时,this
不再指向您的ObjectProvider
实例。要解决此问题,您可以使用ajax来提供有用的context
属性:
function ObjectProvider(){
this.url = "ajax/inbounds.php"
this.inBounds = function(){
this.removeMarkers();
var url_string = this.url;
$.ajax({
url: this.url,
dataType: "json",
context: this,
success: function(data) {
for( i=0; i != data.length; ++i ){
this.createObject( data[i] );
}
});
};
this.createObject = function(_data){};
this.removeMarkers = function(){};
};
否则您可以使用bind:
$.getJSON(url_string, function(data) {
for( i=0; i != data.length; ++i ){
this.createObject( data[i] );
}
}.bind(this));
为了创建一个“绑定”到特定上下文对象的新函数,但仅限于支持ES5或具有垫片的浏览器(如上面描述的链接所示)。
还有提到的版本,存储实例的闭包,但我个人更喜欢避免在没有严格必要的时候。如今,对于这种行为,它被认为是一种古老的做法。
谈论闭包:你不需要在构造函数中声明函数。通过这种方式,它们会一直动态添加,如果它们无法访问某些内部变量,则没有理由,这只是浪费资源。为了清楚起见,在你的情况下,如果你有:
var a = new ObjectProvider();
var b = new ObjectProvider();
console.log(a.createObject === b.createObject) // false
更好的方法可能是:
function ObjectProvider() {
}
ObjectProvider.prototype = {
constructor: ObjectProvider,
url: "ajax/inbounds.php",
inBounds: function () { /* ... */ },
createObject: function () { /* ... */ },
removeMarkers: function () { /* ... */ }
}
var a = new ObjectProvider();
var b = new ObjectProvider();
console.log(a.createObject === b.createObject) // true
但是在那时,如果你没有任何动态属性(例如,URL总是相同的,不作为参数传递给构造函数),也许你不需要有不同的实例,你可以随时随地:
var ObjectProvider = {
url: "ajax/inbounds.php",
inBounds: function () { /* ... */ },
createObject: function () { /* ... */ },
removeMarkers: function () { /* ... */ }
};
并将其用作“单身人士”:
ObjectProvider.createObject()