Intellisense “的打字解释”;这";$.ajax()中的关键字
我意识到TypeScript编译器正试图忠实于普通的旧JavaScript,因为TypeScript实际上就是JavaScript。然而,Intellisense解释为“this”关键字的内容与它在运行时实际解析为的内容之间存在脱节。例如,考虑以下类型的Ajax调用:Intellisense “的打字解释”;这";$.ajax()中的关键字,intellisense,typescript,Intellisense,Typescript,我意识到TypeScript编译器正试图忠实于普通的旧JavaScript,因为TypeScript实际上就是JavaScript。然而,Intellisense解释为“this”关键字的内容与它在运行时实际解析为的内容之间存在脱节。例如,考虑以下类型的Ajax调用: getAgencies() { var self = this; $.ajax(liveString + "/Home/GetSupportedAgencies
getAgencies() {
var self = this;
$.ajax(liveString + "/Home/GetSupportedAgencies",
{
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: Utilities.Logger.displayAjaxError,
success: this.onGetAgenciesComplete
});
}
及其相应的回调:
onGetAgenciesComplete(agencies) {
var self = this;
if (agencies == null)
Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again.");
else {
$.each(agencies, function (i, a) {
self._indexViewModel.agencies.push({ name: a.Name, fullName: a.FullName, shortName: a.ShortName, bbox: a.BBox, countryCode: a.CountryCode });
});
if (Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
self.initMapPage(position, self);
},
function (error) {
Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later.");
});
}
else {
Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information.");
self.getBusRoutes(self.agencyName);
}
// end of initialization
}
}
现在,当我将鼠标悬停在TypeScript源文件中onGetAgenciesComplete中的行“var self=this”上时,变量“self”的Intellisense定义表明它属于HomePageViewModelBase类型,其中HomePageViewModelBase是包含上述方法的类
生成的上述Javascript如下所示:
HomePageViewModelBase.prototype.getAgencies = function () {
var self = this;
$.ajax(liveString + "/Home/GetSupportedAgencies", {
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: Utilities.Logger.displayAjaxError,
success: this.onGetAgenciesComplete
});
};
HomePageViewModelBase.prototype.onGetAgenciesComplete = function (agencies) {
var self = this;
if(agencies == null) {
Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again.");
} else {
$.each(agencies, function (i, a) {
self._indexViewModel.agencies.push({
name: a.Name,
fullName: a.FullName,
shortName: a.ShortName,
bbox: a.BBox,
countryCode: a.CountryCode
});
});
if(Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
self.initMapPage(position, self);
}, function (error) {
Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later.");
});
} else {
Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information.");
self.getBusRoutes(self.agencyName);
}
}
};
当在HomePageViewModelBase.prototype.onGetAgenciesComplete中执行变量“self”时,会将其解析为类似于AjaxContext的内容,而不是HomePageViewModelBase的实例。这是预期的行为还是我应该将其报告为错误?是的,您可能应该将其报告为错误,因为
$.ajax()
中的this
是指$.ajax()
对象本身
如果您想绕过它使其工作,请将成功函数更改为:
success: self.onGetAgenciesComplete
或者,如果您希望this
代表您的类,只需使用$.ajax的context方法即可
$.ajax({
context: this,
// now *this* will come from the previous scope,
// which in your case, is your class "HomePageViewModelBase"
// now that we know for certain what -this- refers to
success: this.onGetAgenciesComplete
});
就任何(包括智能感知)静态分析而言,onGetAgenciesComplete
的上下文是HomePageViewModelBase
,并且始终是;除了在运行时,上下文将通过显式的内部jQuery.ajax上下文绑定动态设置。Intellisense确定上下文将动态更改的唯一方法是实际执行该代码路径,但即使这样也会导致歧义:哪个上下文是正确的上下文
如果您在其他地方“借用”了一种方法,用于一次性调用,该怎么办?Intellisense是否应该使用该调用站点来确定上下文?可能不是
HomePage.prototype.onGetAgencies.call({ some other context }, ...);
(为了可读性而缩短。)回答得好-设置上下文很有效。在提交bug之前,请考虑以下问题:当函数可以在许多不同的上下文中调用时,编译器如何正确推断<代码>上下文>代码>。我相信它显示了正确的上下文,这是基于直接调用函数的假设,而不是在从其他地方回调的上下文中。我同意,如果有什么好的做法(如果有什么,但也为了可读性),那么让人清楚地知道
this
的上下文应该是什么。我认为@KNji的观点是,它不应该知道这是$.ajax本身,因为这就是它在jQuery中的工作方式吗?@mcpDESIGNS,这是一个很好的解释,谢谢。我从来不知道$.ajax上下文是一个更好的解决方案。多谢。在我的帖子中,您的观点也是正确的,即intellisense不应该在$.ajax中将“this”引用到HomePageViewModel base的实例中。