从属性值中获取属性键

TBE*_*TBE 7 javascript javascript-objects

给出以下javascript对象:

var commands = {
    back:{
        command: "b",
        aliases: ["back","go back","backwards"],
        action: function(){
            return this.key; //I want this to return "back" (the prop name)
        },
        desc: "goes back"
    }
}
Run Code Online (Sandbox Code Playgroud)

如何从action()?中访问"返回"的属性名称?

我认为它应该很简单,但如果它不是简单的东西,我会添加更多的细节.

  • 注意:aliases[0]偶然保留名称,并且不承诺将来或其他命令保留它.

编辑:有时我们会变得复杂,而我们可以很快解决问题.在这种情况下,我可以继续并返回字符串"返回"

如果有这样的解决方案,我会留下问题并接受解决我问题的答案.

Nan*_*ard 2

返回您提到的字符串绝对是最简单的方法。但我可以看到有人可能希望能够通过动态创建的对象获得类似的功能,其中的键直到运行时才知道。

在这种情况下可行的解决方案是将commands对象暴露给子对象,以便它们可以自行查找:

var commands = {
    back:{
        command: "b",
        aliases: ["back","go back","backwards"],
        action: function(){
            var commandKeys = Object.keys(commands);
            for(var i=0; i < commandKeys.length; i++){
                if(commands[commandKeys[i]] === this){
                    return commandKeys[i];
                }
            }
        },
        desc: "goes back"
    }
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,在所有这些操作对象之间共享该函数也可能更有意义:

var commands = {
    back:{
        command: "b",
        aliases: ["back","go back","backwards"],
        action: getAction,
        desc: "goes back"
    },
    forward: {
        //...
        action: getAction,
        //...
    }
};

function getAction() {
    var commandKeys = Object.keys(commands);
    for(var i=0; i < commandKeys.length; i++){
        if(commands[commandKeys[i]] === this){
            return commandKeys[i];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

除非你需要对每个子对象执行一些特定的逻辑。


编辑:为了提高效率,我们可以将其设置为getAction不执行每次调用的函数,并添加一个用于存储名称的属性。这样,查找仅在第一次发生。

var commands = {
    back:{
        command: "b",
        aliases: ["back","go back","backwards"],
        action: getAction,
        desc: "goes back"
    },
    forward: {
        //...
        action: getAction,
        //...
    }
};
// Only needs to getKey the first time called.
function getAction() {
    if(!this.key) this.key = getKey(this);
    return this.key;
}
function getKey(obj) {
    var commandKeys = Object.keys(commands);
    for(var i=0; i < commandKeys.length; i++){
        if(commands[commandKeys[i]] === obj){
            return commandKeys[i];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)