我是一个javascript新手,所以到目前为止,由于我缺乏经验以及它与我习惯的语言有多么不同,所以我写的是丑陋的代码,所以我在下面发布的代码有效,但是我想知道我是以正确的方式做到的,还是可行的,但这是一种可怕的做法,或者有更好的方式。
基本上,我有一个小伙伴在网格内移动,他从服务器接收一个动作,他可以向8个方向移动(int):0:向上,1:向上 - 向右,2:向右...... 7:左上角。
服务器将向他发送此0 <= action <= 7
值,并且他必须采取正确的操作...现在,而不是使用switch-case结构。我创建了一个函数goUp(),goLeft()等,并将它们加载到一个数组中,所以我有一个像这样的方法:
var getActionFunction = actions[action];
actionFunction();
但是,如何设置这一切是:
1)创建一个构造函数:
function LittleDude(container) {
this.element = container; //I will move a div around, i just save it in field here.
}
LittleDude.prototype.goUp() {
//do go up
this.element.animate(etc...);
}
LittleDude.prototype.actions = [LittleDude.prototype.goUp, LittleDude.prototype.goUpLeft, ...];
//In this array I can't use "this.goUp", because this points to the window object, as expected
LittleDude.prototype.doAction = function(action) {
var actionFunction = this.actions[action];
actionFunction(); //LOOK AT THIS LINE
}
现在如果你注意了,最后一行将不起作用..因为:当我使用索引访问数组时,它返回一个LittleDude.prototype.goUp例如...所以“this”关键字是未定义..
goUp有一个声明“this.element”...但是“this”没有定义,所以我必须这样写:
actionFunction.call(this);
所以我的doAction将如下所示:
LittleDude.prototype.doAction = function(action) {
var actionFunction = this.actions[action];
actionFunction.call(this); //NOW IT WORKS
}
我需要知道这是否是hackish,或者我是否违反某种“不要做这个”规则。或者也许它可以用更好的方式编写。因为在我看来有点奇怪的是将它添加到原型中,然后将其视为一个独立的功能。
答案 0 :(得分:3)
您要做的是可能的方法之一,但可以使其更简单。由于对象属性名称不是必需的字符串,因此可以直接在原型上使用动作索引。您甚至不需要doAction
功能。
LittleDude = function LittleDude(container) {
this.container = container;
}
LittleDude.prototype[0] = LittleDude.prototype.goUp = function goUp() {
console.log('goUp', this.container);
}
LittleDude.prototype[1] = LittleDude.prototype.goUpRight = function goUpRight() {
console.log('goUpRight', this.container);
}
var littleDude = new LittleDude(123),
action = 1;
littleDude[action](); // --> goUpRight 123
littleDude.goUp(); // --> goUp 123
答案 1 :(得分:1)
actionFunction.call(this); //NOW IT WORKS
我需要知道这是否是hackish,或者我是否违反某种情况&#34;不要这样做&#34;规则。或者也许它可以用更好的方式编写。
不,使用.call()
完全可以绑定this
keyword - 这就是它所做的事情。
因为在我看来有点奇怪的是将它添加到原型中,然后将其视为一个独立的功能。
如果您不直接使用它们,则不必在原型上定义它们:-)但是,如果您这样做,您可能不会将函数本身存储在数组中,但方法姓名然后使用bracket notation调用它们:
// or make that a local variable somewhere?
LittleDude.prototype.actions = ["goUp", "goUpLeft", …];
LittleDude.prototype.doAction = function(action) {
var methodName = this.actions[action];
this[methodName](); // calls the function in expected context as well
}