我正在尝试学习javascript。作为这项努力的一部分,我正在编写一个基本的极小极大AI。我有以下方法:
Computer.prototype.expand = function(node) {
/* adds all state action pairs to the node.successors array */
};
Computer.prototype.getMove = function(boardAr) {
console.log("getMove");
var b2 = boardAr.slice();
var i;
var action;
this.root = new TNode(b2, this.mark);
this.root.AIPlayedLast = false;
this.expand(this.root);
this.root.successors.forEach(this.minVal);
action = maxNode(root.successors);
this.draw(action);
registerMove(action, this.mark);
};
Computer.prototype.minVal = function(node) {
if (node.isTerminal) {
return;
} else {
this.expand(node);
node.successors.forEach(maxVal);
node.utility = this.minNode(node.successors).utility;
}
};
调用getMove
方法后,对expand
的后续调用按预期进行。但是,当我从expand
方法调用minVal
时,我得到:Uncaught TypeError: undefined is not a function
。我对此完全感到困惑。任何帮助/建议将不胜感激。
答案 0 :(得分:3)
我认为原因在于这一行:
this.root.successors.forEach(this.minVal);
您将minVal作为无上下文引用传递,它不会在您的计算机实例的上下文中调用(此)
以下是如何改进它:
var self = this;
this.root.successors.forEach(function() {
self.minVal.apply(self,arguments);
})
答案 1 :(得分:2)
最简单,最快捷的解决方案就是改变
this.root.successors.forEach(this.minVal);
到
this.root.successors.forEach(this.minVal.bind(this))
这解决了与其他答案相同的问题,但在某种程度上可能会考虑更紧凑。
或者,您可以将“this”作为第二个参数传递给forEach
函数,这是forEach
的一个未充分利用的功能:
this.root.successors.forEach(this.minVal, this)
此功能也可用于其他Array
原型方法,这些方法包含map
,filter
,some
,every
(但不是{{} 1}}和reduce
)。
ES6箭头功能以不同方式处理reduceRight
,因此您可以执行
this
答案 2 :(得分:0)
可能会为每个后继者调用forEach()方法。所以,你传递了Computer :: minVal方法(this.minVal),但是将TNode(?)作为这个指针。尝试:
var that = this;
this.root.successors.forEach(function(node) {
that.minVal(node));
});