Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the property key from within a property's value

Given the following javascript object:

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"
    }
}

How can i access the Property Name which is "back" from within the action()?

I think it should be pretty simple, but if it isn't something simple than I'll add more details.

  • NOTE: aliases[0] is holding the name by chance, and it is not promised to hold it in the future or in other commands.

EDIT: Sometimes we get to complicated while we can solve the problem pretty fast. In this case i can just go ahead and return the string "back"

I'll leave the question and accept the answer that solves my question if there is such a solution.

like image 306
TBE Avatar asked Nov 30 '15 11:11

TBE


People also ask

How do I find the key name of an object?

Use object. keys(objectName) method to get access to all the keys of object. Now, we can use indexing like Object. keys(objectName)[0] to get the key of first element of object.

How do I check if an object contains a key?

You can use the JavaScript in operator to check if a specified property/key exists in an object. It has a straightforward syntax and returns true if the specified property/key exists in the specified object or its prototype chain. Note: The value before the in keyword should be of type string or symbol .


1 Answers

Returning the string as you mentioned is definitely the easiest way. But I could see cases where someone might want to be able to get similar functionality with a dynamically created object in which the keys are not known until run-time.

A solution that would work in that case is exposing the commands object to the sub objects, so they can look themselves up:

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"
    }
};

In this case it may also make more sense to share the function across all those action objects:

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];
        }
    }
}

Unless you need to perform some specific logic for each sub object.


EDIT: To improve efficiency, we can make it where the getAction function is not executed every call and add a property that will store the name. That way the lookup only occurs the first time.

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];
        }
    }
}
like image 142
NanoWizard Avatar answered Nov 10 '22 17:11

NanoWizard