【发布时间】:2017-07-11 14:21:20
【问题描述】:
我最近对 Screeps 上瘾了,我重构了一些代码以创建基于任务的实现。任务是诸如“步行然后收获直到你满负荷”之类的东西,它基于一个编写为 ES6 样式类的单个基本任务模板。 Creeps 可以通过加载相关任务文件并返回新任务实例的包装器 (tasks.js) 分配任务。
今天我遇到了一个奇怪的错误,让我觉得我没有完全理解 Javascript 的继承模型。下面是相关代码:
Task.js:(基础任务类)
class Task {
constructor(taskName) {
// Parameters for the task
this.name = taskName; // name of task
this.quiet = false; // suppress console logging if true
this.creep = [creep assigned to this task]
this.target = [thing task operates on, e.g. "repair this wall"]
...
}
...
// Execute this task each tick. Returns nothing unless work is done.
step() {
...
if (creep.pos.inRangeTo(target, this.targetRange)) {
var workResult = this.work();
console.log(this.quiet) // < returns false, should be true?
if (workResult != OK && this.quiet == false) {
creep.log("Error: " + workResult); // < is printed when run
}
return workResult;
} [else move to target]
}
...
// Task to perform when at the target
work() {
// overwrite this in child class
}
}
module.exports = Task;
task_harvest.js:(收获任务)
var Task = require('Task');
class taskHarvest extends Task {
constructor() {
super('harvest');
// no mention of this.quiet here
}
...
work() {
console.log("harvest:" + this.quiet);
return this.creep.harvest(this.target);
}
}
module.exports = taskHarvest;
tasks.js:(通过函数调用生成新任务实例的包装器)
module.exports = function (taskName) {
var TaskClass = require('task_' + taskName); // all tasks follow this naming pattern
var taskInstance = new TaskClass;
return taskInstance;
};
harvester.js:(收割机蠕变的行为模型)
var tasks = require('tasks');
var roleHarvester = {
...
harvest: function (creep) {
var target = Game.getObjectById(creep.memory.assignment);
var taskHarvest = tasks('harvest');
taskHarvest.quiet = true; // < this task shouldn't print anything
creep.assign(taskHarvest, target); // assigns to creep.task
return OK;
},
...
run: function (creep) { // executed every tick
// execute the task
creep.task.step();
},
...
}
当我分配一个从源中获取的cree 时,我从task_harvest.js 创建一个新任务,将其quiet 属性设置为true,并将它及其目标绑定到cree。一旦cree有一个任务,它就会被指示运行它,直到它变得无效(代码未包含在上面)。 Cree 可以正常执行任务,但仍会将所有内容记录到控制台。
我认为在harvester.js 中,当我设置taskHarvest.quiet = true; 时,从Task.js 导入的行为会将this.quiet 视为true。然而,似乎情况并非如此。在roleHarvester 中,运行console.log(creep.task.quiet) 返回true,但在Task 中,当cree 执行分配的任务时运行console.log(this.quiet) 会得到false。
我可以将quiet 作为可选参数添加到构造函数中,但这很复杂,我想知道为什么我正在做的事情不起作用。
【问题讨论】:
-
当您检查
this.quiet的值时,您是否100% 确定this是正确的?对于你的继承权,我看不出有任何明显的错误或误解。设置taskHarvest.quiet = true;应该可以正常工作。 -
@jfriend00 在Task.js 中,
this应该引用Task,在task_harvest.js 中,this应该引用taskHarvest,它没有定义this.quiet,所以它应该引用继承的 Task.js 变量。然后,当我创建taskHarvest的实例并设置它的instance.quiet = true时,它似乎并没有改变从Task继承的值。如果我执行console.log(instance.quiet),它会返回true,但如果我到达Task并执行console.log(this.quiet),它会返回false。 -
我没有问你它“应该”是什么。我问你实际上是什么。这里只有两种可能。其他东西正在将
.quiet设置回false,或者您稍后不再查看同一个对象。你必须弄清楚它是哪一个。您没有显示足够的代码让我们跟踪对象的生命周期以及可能发生的所有事情。例如,我不知道creep.assign()做了什么。它可能正在复制对象,在其上设置一些属性等等...... -
仅供参考,您可以添加一个用于调试目的的特殊属性,例如
taskHarvest._test = "hello";,然后查看该属性是否仍然存在于step()和console.log("_test:", this._test)中,以查看您是否仍然拥有相同的对象。
标签: javascript class inheritance ecmascript-6 screeps