当您拨打action如下:
commands.back.action();
action 的范围是back。遗憾的是,分配给commands.back 的对象的创建并不知道action 内部的this 被称为"back"。据我了解,这样做是因为我们可以将分配给commands.back 的对象分配给另一个名称的对象。如:
var foo = { f: function(){console.log(this) } };
var bar = foo;
bar.f();
或者更接近你所拥有的......
var foo = {
bar: {
f:function(){console.log(this)}
}
};
var other = { another: (foo.bar) };
我知道对象在哪里知道它在其中创建的名称的唯一方法是函数。因此,我们可以创建一个名为 back 的临时函数,它将根据需要创建一个对象。
var commands = {
back:(new function back(){
// I prefer to assign to a variable to assist with the readability as to what "this" is:)
var self = this;
self.command = "b";
self.aliases = ["back","go back","backwards"];
self.action = function(){
// Can leave as "this" or change to "self".
return this.key;
};
self.desc = "goes back";
self.key = self.prototype.constructor.name;
})
}
最简单的解决方案
但此时还不如添加一个已经具有名称的属性。我建议创建一个名为 key 或 name 的属性,而不是将名称直接放入 action 函数中,以便更容易在多个位置使用该名称。此外,如果需要,允许在一个地方更改对象内的名称。
var commands = {
back:{
command: "b",
aliases: ["back","go back","backwards"],
action: function(){
return this.key;
},
desc: "goes back",
key: "back"
}
}
编辑:将此编辑添加为另一种方法,但我仍会使用以前的方法。我们可以利用Object.keys 来获取属性的名称,因为back 被添加为commands 的可枚举属性。
var i = 0,
commands = { back: {
key: (function(id){return function(){return Object.keys(commands)[id]}})(i++)
}}
然后可以通过以下方式获取key:
commands.back.key();
或在action 函数内为:
this.key();
可以将key 添加到back 作为get,如下所示:
var i = 0,
commands = { back: {
id: (i++),
get key() {return Object.keys(commands)[this.id]}
}}
这将允许您以commands.back.key 的身份访问该属性,并在action 函数中以this.key 的身份访问该属性。
还可以预先定义所有内容,然后可以执行以下操作:
var i = 0, commands = { back: undefined };
commands.back = { key: Object.keys(commands)[i++] };