Andrey Bushman
Andrey Bushman

Reputation: 12476

How to get the property name as a string?

My simple example:

let a = { foo : 5}, b = { stuff : 7};
let func = function(obj, prop) { ++obj[prop]; }
func(a, 'foo');
func(b, 'stuff');

When I call func I set the property name as string literal directly. If I want to rename the property late (in my code source) then I have to change the string literal too. Is it possible to get the property name as a string in runtime instead of using the string value as a literal?

UPD (for clarity)

In my project, I have some classes each of them has a property which contains an array. But this property has the different name for each class. I have a logic for handling these arrays content. This logic is the same for each class. Right now I pass the property name as a string literal, but if I later rename these properties in my code source then I must to change and the string literals too. If I forget to do it I will have a problem. So I want to get rid of the use of string literals in this task.

Upvotes: 0

Views: 146

Answers (1)

Touffy
Touffy

Reputation: 6561

I think what you're trying to do is a bad idea. If something behaves the same in different objects, call it the same name. But hey, there's an ES6 concept for that!

Symbols are used by JavaScript to support similar behaviour in different "classes". So let's do that here.

Let's create a Symbol:

const incrementableProp = Symbol("incrementableProp")

First, let's store the name of the property in your object that should have the behaviour:

const a = {
    specialProp: [],
    [incrementableProp]: "specialProp"
}

The Symbol itself will always be the same, so the increment function can find it reliably:

function incrementProp(obj) {
    if(incrementableProp in obj)
        obj[obj[incrementableProp]]++
    else throw new TypeError("This object does not support an incremental property.")
}

Lastly, let's make sure you need to change the name only once by removing the Symbol definition in the object. We'll use a decorator for that:

function special(target, key, descriptor) {
    target[incrementableProp] = key
    return descriptor
}

So now you can do this:

const a = {
    @special specialProp: []
}

Upvotes: 1

Related Questions