1

Is it possible to reference the name of the object variable declaration within the object itself? Something like:

const foo = {
  bar: `${MAGICTHIS}-bar`,
}

console.log(foo.bar); //foo-bar

EDIT:

I am writing a dynamic function for rewriting all my css classnames to BEM in an object. I do this to be able to manage them in one point through out my application. Without the function it is like this:

export const button = {
  btn: 'button',
  btnSm: 'button--small',
  btn2: 'button--secondary',

export const alert = { 
  alert: 'alert',
  alertDanger: 'alert--danger',
//etc
}

They are separated in different objects because I want to isolate usage. I wanted to optimize this since I'll be doing this a lot. That's why I'm trying to write a 'bemmify' function. So I can do this:

export const button = {
  btn: bemmify(),
  btnSm: bemmify('small'),
  btn2: bemmify('secondary'),

export const alert = { 
  alert: bemmify(),
  alertDanger: bemmify('danger'),
//etc
}

And have the same result as the objects above. Of course I could always pass the 'base' as a first param (bemmify('button', 'small')) but I started to wonder if it were possible to let my bemmify function be so smart that it could recognize the name of the object it is in.

Robbeoli
  • 408
  • 5
  • 17
  • https://stackoverflow.com/questions/5448135/how-to-get-objects-name-in-javascript – benvc May 13 '19 at 17:44
  • 2
    I don't believe that's entirely similar to my question. – Robbeoli May 13 '19 at 17:48
  • Not exactly the same, which is why I didn't mark it as a dup, but the answer is the same. – benvc May 13 '19 at 17:52
  • This is definetly not what you need for your app. This is an XY problem. – Jonas Wilms May 13 '19 at 17:54
  • 4
    This may be an "xy problem". Can you share more information about your actual need? Why are you trying to accomplish this? – StriplingWarrior May 13 '19 at 17:54
  • 2
    If you do `foo2 = foo;`, what do you expect `foo2.bar` to return? – Barmar May 13 '19 at 17:58
  • Objects don't have names. When you assign an object to a variable, there's nothing that references backwards from the object to the variable. – Barmar May 13 '19 at 17:58
  • 2
    `const MAGICTHIS = 'foo';` – Kevin B May 13 '19 at 18:06
  • I updated my question to be less XY. – Robbeoli May 13 '19 at 18:35
  • 2
    The closest you could get to your intended result would be to reorganize bemmify and how you're code works such that bemmify accepts a value, and an object to populate that you then set to the variable that is named after the value. however... at that point you mightaswell just do each one manually. It's impossible to determine the name of the variable a value is stored in. – Kevin B May 13 '19 at 18:36
  • @Barmar, I have no use for a duplicate object, so for this use case it wouldn't matter what it would return. So a solution returning either would be fine. If it were to return `foo2-bar` it would would be pretty cool though – Robbeoli May 13 '19 at 18:38

1 Answers1

5

Whenever you find yourself writing code where the variable names are significant, you should generally be using an object where the variable names are keys. So you should have an object like:

const bem_data = {
  button: {
    btn: 'button',
    btnSm: 'button--small',
    btn2: 'button--secondary',
  },
  alert: {
    alert: 'alert',
    alertDanger: 'alert--danger',
  }
}

Then you can use a function to create each element:

function add_element(data, key, prefix, additional) {
  const obj = {
    [prefix]: key
  };
  Object.entries(additional).forEach(([
    keySuffix,
    valSuffix
  ]) => obj[prefix + keySuffix] = `${key}--${valSuffix}`);
  data[key] = obj;
}

const bem_data = {};
add_element(bem_data, "button", "btn", {
  Sm: "small",
  "2": "secondary"
});
add_element(bem_data, "alert", "alert", {
  Danger: "danger"
});

console.log(bem_data);

Then you export bem_data and use bem_data.button, bem_data.alert, etc.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Wow, that's some good code. The only downside I see is in the exports. I would manually have to export `bem_data.button`, `bem_data.alert`, and all the other objects, right? – Robbeoli May 13 '19 at 19:21
  • No, just export `bem_data`. – Barmar May 13 '19 at 19:22
  • I don't know what BEM is, so I don't see why they need to be individual variables. – Barmar May 13 '19 at 19:22
  • But if I want isolated usage of one of the sub objects? – Robbeoli May 13 '19 at 19:23
  • Just use `bem_data.button`, `bem_data.alert`. – Barmar May 13 '19 at 19:24
  • I've been trying out some code myself. But I'm wondering if it's dirty because of the global variable. What do you think of this? https://codesandbox.io/s/0q6239wqyp – Robbeoli May 13 '19 at 19:31
  • 1
    Functions shouldn't depend on the order they're called, unless it's inherent in the purpose of the function (e.g. I/O functions obviously have to be called in an appropriate order). The way you're using the `base` global variable seems like poor style. – Barmar May 13 '19 at 19:38
  • Thanks for clarifying, your way seems better in that case. – Robbeoli May 13 '19 at 19:53