【发布时间】:2012-10-05 14:48:58
【问题描述】:
我正在开发的 API 有问题。我想要一个类数组,每个类都实现相同的接口并具有静态方法。我将有另一个类,它将循环遍历类数组并根据其中一个静态方法的返回值选择一个,但是编译器正在删除静态方法,并且 javascript 在尝试调用静态方法时遇到 TypeError .我试过搜索几个论坛,但我找不到任何有用的东西。这个错误只出现在高级编译模式下,不简单,甚至在debug模式下高级编译也会出现。
我认为这是因为编译器没有意识到我正在使用该函数,因为我调用它的方式很复杂。
我整理了一个稍微简化的示例,说明我正在尝试执行的操作会导致错误。
代码见下:
Racer 接口是由两个类实现的接口:Runner 和Jogger。该接口有一个名为 getModesOfTransportation 的静态方法,它返回一组赛车可以移动的方式,以及一个名为 getTransportationModes 的实例方法,它执行相同的操作。该文件还定义了一个自定义类型racing.RacerClass,它(我认为)创建一个类型,该类型是一个函数,当使用new 关键字调用时会返回一个赛车对象。我根据https://developers.google.com/closure/compiler/docs/js-for-compiler#types 形成了这个。我认为我应该定义该类型也有一个静态方法,但我不知道如何。这种自定义类型会不会是错误的罪魁祸首?
racer.js:
goog.provide('racing.Racer');
/** @typedef function(new:racing.Racer)*/
racing.RacerClass={};// My custom typedef
/**
* Interface for racers.
* @interface
*/
racing.Racer=function(){};
/**
* Gets the ways this racer can move.
* @return {Array.<string>} The ways this racer can move.
*/
racing.Racer.getModesOfTransportation=function(){}
/**
* Gets the ways this racer can move.
* @return {Array.<string>} The ways this racer can move.
*/
racing.Racer.prototype.getTransportationModes=function(){}
Helper 类存储 Racer 构造函数列表。 registerRacer 函数接受 Racer 的构造函数并将其添加到列表中。传递的构造函数也会有一个静态的getModesOfTransportation 函数。 getRacers 函数返回已注册的赛车手列表。
helper.js:
goog.provide('racing.Helper');
/**
* A collection of functions to help with finding racers.
*/
racing.Helper={};
/**
* An array of racers.
* @type {Array.<racing.RacerClass>}
* @private
*/
racing.Helper.racers_=[]
/**
* Adds the given racer to the list.
* @param {racing.RacerClass} racer A racer to add to the list of racers.
*/
racing.Helper.registerRacer=
function(racer){
racing.Helper.racers_.push(racer);
}
/**
* Gets an array of registered racers.
* @return Array.<racing.RacerClass> A list of all registered racers.
*/
racing.Helper.getRacers=
function(){
return racing.Helper.racers_;
}
Jogger类实现了Racer接口,这两个函数的返回值为['jog']文件末尾,向helper注册自己。
jogger.js:
goog.provide('racing.Jogger');
goog.require('racing.Racer');
goog.require('racing.Helper');
/**
* This racer can jog.
* @constructor
*/
racing.Jogger=function(){
console.log('Jogger is going');
};
/**
* Gets the ways this racer can move.
* @static
* @return {Array.<string>} The ways this racer can move.
*/
racing.Jogger.getModesOfTransportation=
function(){
return ['jog'];//I can jog
}
/**
* Gets the ways this racer can move.
* @return {Array.<string>} The ways this racer can move.
*/
racing.Jogger.prototype.getTransportationModes=
function(){
return ['jog'];//I can jog
}
//Register this racer
racing.Helper.registerRacer(racing.Jogger);
Runner类也实现了Racer接口,但是这两个函数的返回值是['run']文件末尾,它自己注册了helper。
runner.js:
goog.provide('racing.Runner');
goog.require('racing.Racer');
goog.require('racing.Helper');
/**
* This racer can run.
* @constructor
*/
racing.Runner=
function(){
console.log('Runner is going');
};
/**
* Gets the ways this racer can move.
* @static
* @return {Array.<string>} The ways this racer can move.
*/
racing.Runner.getModesOfTransportation=
function(){
return ['run'];//I can run
}
/**
* Gets the ways this racer can move.
* @return {Array.<string>} The ways this racer can move.
*/
racing.Runner.prototype.getTransportationModes=
function(){
return ['run'];//I can run
}
//Register this racer
racing.Helper.registerRacer(racing.Runner);
Organizer 类有一个名为startRace 的公共函数,它获取并存储Racer 的一个实例,该实例可以通过调用受保护的getRunner 函数来运行。 getRunner 函数在竞速者列表中循环并试图找到一个可以运行的,但是,一旦代码被编译,racerClass.getModesOfTransportation() 就会失败,指出 getModesOfTransportation 未定义。
organizer.js:
goog.provide('racing.Organizer');
goog.require('racing.Helper');
goog.require('goog.array');
/**
* Class that helps with starting a race.
* @constructor
*/
racing.Organizer=function(){}
/**
* A racer that can run.
* @protected
* @returns {racing.Racer}
*/
racing.Organizer.prototype.runner=null;
/**
* Get a racer that can run.
* @protected
* @returns {racing.Racer}
*/
racing.Organizer.prototype.getRunner=
function(){
//Cycle through the racers until we find one that can run.
goog.array.findIndex(racing.Helper.getRacers(),
function(racerClass){
if(goog.array.contains(racerClass.getModesOfTransportation(),'run')){
this.runner=new racerClass();
return true;
}
else return false;
},this
);
}
/**
* Starts a race.
*/
racing.Organizer.prototype.startRace=
function(){
this.runner=this.getRunner();
}
最终文件只包含编译器的所有类。
api.js:
//Include the racers
goog.require('racing.Runner');
goog.require('racing.Jogger');
//Include the organizer and export its properties
goog.require('racing.Organizer')
goog.exportSymbol('racing.Organizer', racing.Organizer);
goog.exportProperty(racing.Organizer.prototype, 'startRace', racing.Organizer.prototype.startRace);
在调试模式下对编译代码运行new racing.Organizer().startRace();,会产生以下错误,当我查看编译代码时,getModesOfTransportation 函数不再存在:
Uncaught TypeError: Object function () {
console.log("Runner is going")
} has no method '$getModesOfTransportation$'
$$racing$Organizer$$$$$startRace$$
(anonymous function)
我希望能够使其工作,而不必将类拆分为仅具有静态函数的类和仅具有构造函数的类,因为这会使代码混乱。我试图弄清楚这一点,但我做不到。
提前感谢您的任何想法/建议。
【问题讨论】:
标签: javascript static-methods google-closure-compiler google-closure google-closure-library