我意识到打字稿编译器正在尝试保持型纯旧javascript,因为Typescript确实是JavaScript。但是,Intellisense将其解释为"此"关键字的内容与在运行时实际解决的问题之间存在脱节。例如,考虑以下打字稿AJAX调用:
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中执行变量时,可以解决看起来像AjaxContext的内容,而不是HomePageViewModelBase的实例。这是预期的行为还是我应该将其报告为错误?
是的,您可能应该将其报告为错误,因为$.ajax()
中的this
旨在参考$.ajax()
对象本身。
如果您想绕过它,以便它有效,请将您的成功函数更改为:
success: self.onGetAgenciesComplete
或如果您想要 this
代表您的课程,请使用上下文 $ .ajax的方法
$.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
});
就任何(包括Intellisense)静态分析而言,onGetAgenciesComplete
is的上下文是 HomePageViewModelBase
,并且永远是;除了在运行时,上下文将通过显式内部jQuery.ajax上下文绑定而动态设置。IntelliSense可以确定上下文将动态变化的唯一方法是实际执行该代码路径,但即使这也导致了歧义:哪个上下文是正确的上下文?
如果您在其他地方"借"一种方法,该怎么办?IntelliSense是否应该使用该呼叫站点来确定上下文?可能不是...
HomePage.prototype.onGetAgencies.call({ some other context }, ...);
(缩短了可读性。)