-2

I understand that in ES2015+, instead of writing:

let myObject = { a: "a", b: "b", c: "c" };

I can use object shorthand to write the following:

let a = "a";
let b = "b";
let c = "c";

let myObject = { a, b, c };
console.log(myObject);

But that doesn't resemble the shorthand I am looking for.

Is there an approach in which I can declare an object literal without first defining variables and the properties of that object literal will be automatically assigned values which are stringified versions of the object's property names?

I.e. I write something similar to this:

let myObject = { a, b, c };

and it automatically resolves as:

let myObject = { a: "a", b: "b", c: "c" };

Or is that kind of shorter shorthand simply not possible?


Some background to this question:

My use-case is accepting both values and name-value pairs from users. The latter is straightforward enough. In the case of the former, I don't wish to make the user jump through the hoop of adding a name and then an identical value where one would suffice.

Rounin
  • 27,134
  • 9
  • 83
  • 108
  • 2
    simply no . . . – Nina Scholz Oct 31 '20 at 10:41
  • 1
    Such an object wouldn't be particularly useful, because it's a mapping from a value you already have to that same value (`obj["foo"] === "foo"`, for example, but you already had `"foo"`). You could make a [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) that just returns the name of the prop you asked for, but it might help to provide some context on why you'd need this. – jonrsharpe Oct 31 '20 at 10:48
  • Thanks, both of you. My use-case is accepting both _values_ and _name-value pairs_ from users. The latter is straightforward enough. In the case of the former, I don't wish to make the user jump through the hoop of adding a _name_ and then an identical _value_ where one would suffice. – Rounin Oct 31 '20 at 10:53
  • 1
    Why not accept either an object or an array, then, and in the case of the array `["a", "b", "c"]` it's a simple transform to the object `{a: "a", b: "b", c: "c"}` using e.g. `.reduce`. – jonrsharpe Oct 31 '20 at 10:57
  • If I have no other option, then yes, my default course of action will be to accept both an _array_ or an _object_. That was where I started and then I wondered if I might not be able to implement something even better. – Rounin Oct 31 '20 at 10:59
  • Just check MDN & ECMAScript specs: there is no such syntax. If your use case is to create a set of keys where the value really is irrelevant, but just the *presence* of the key is what you need, then create a Set: `new Set(["a", "b", "c"])`. – trincot Oct 31 '20 at 11:00
  • @jonrsharpe - if you are content to add your comment above (regarding `.reduce`) as an answer below, I shall be happy to accept. Many thanks. – Rounin Oct 31 '20 at 11:00
  • I'd suggest you give it a go, see if it meets your needs and, if you still have a problem, [edit] to clarify. – jonrsharpe Oct 31 '20 at 11:01
  • 1
    The addition to your question mentions user provided values. So could you add the boiler plate code for the function that would receive such input, and indicate what the output of that function would need to be? I ask, because I can't see how an object *literal* could have anything to do with user input... which is by definition *not* literal. – trincot Oct 31 '20 at 11:06
  • @trincot - My reference to object literals might be a red herring here. It's object syntax than I'm more concerned with. In PHP, you can write `['myValue0', 'myProperty1' => 'myValue1', 'myProperty2' => 'myValue2', 'myValue3']`. I am looking for a way to do something similar in javascript. If it doesn't exist, then it doesn't exist. – Rounin Oct 31 '20 at 11:16
  • 1
    Call it literal or syntax, presumably you're talking about user input in terms of someone creating an object with which to invoke part of the API you're providing (e.g. a library they're consuming). In which case, are you asking about this in terms of documenting how they might do so (do they not know how to create objects)? Or are you proposing that your function implement something that makes it possible? Or are they passing e.g. a string you're planning to parse? – jonrsharpe Oct 31 '20 at 11:26
  • 1
    In case it's helpful, by the way, the suggestion to accept either an object `{ key: val }` *or* an array `[keyAndVal]` was partly inspired by recently reading the Jasmine [`createSpyObj` implementation](https://github.com/jasmine/jasmine/blob/main/src/core/SpyFactory.js) for [another question](https://stackoverflow.com/q/64560390/3001761); you can see in that source how they canonicalise the user's input. – jonrsharpe Oct 31 '20 at 11:33
  • Yes. The last one. The user is submitting a string, which I will parse. I think I'm going to request space-separated values and use objects all the time at my end. If a space-separated value contains an internal separator (eg. `loch^ness`) then I will treat it as a _name-value pair_: `{ loch: "ness" }`. If the value contains no such separator (eg. `loch`), I will treat it as a _value_, though since I am using objects all the time at my end, it will render as: `{ loch: "loch" }`. – Rounin Oct 31 '20 at 11:34
  • In that case I'd strongly recommend using an existing format like JSON, rather than creating yet another one. They can pass either `'{"loch": "ness"}'` or `'["loch"]'`, you get to use an existing (and extremely well-optimised) parser, and nobody has to figure out what happens when the user wants to put a space or caret in the actual value. Note if you're parsing it yourself you're not limited to the existing syntax anyway, you *can* accept `'{ loch }'` instead of `'{ loch: "loch" }'` if you really want to (but... maybe don't). – jonrsharpe Oct 31 '20 at 11:38
  • As to the comparison with PHP, the PHP array `['myValue0', 'myProperty1' => 'myValue1', 'myProperty2' => 'myValue2', 'myValue3']` would translate (roughly) to `{ 0: 'myValue0', 1: 'myValue3', myProperty1: 'myValue1', myProperty2: 'myValue2' }`, which is slightly different from what you ask. – trincot Oct 31 '20 at 11:58
  • @jonrsharpe - Sure. Personally I love JSON as a Serialisation / Data Interchange Format. But this would be the wrong user-audience for that. In terms of Japanese writing systems it would be like (not as extreme but something like) asking for _kanji_ input from students who know only _kana_. – Rounin Oct 31 '20 at 12:01
  • 1
    While I'm sure that resonates culturally as a simile in (checks notes) Huddersfield, I'm not familiar with Japanese writing systems! Without any context of your users I can't tell you what would work best, but it seems like you're asking them to learn *some* means of representing their data. In that case either making it a standard one (so they're learning something portable at least) or removing the need entirely (provide a simpler interface that abstracts away the details of the interchange format) is likely a good move. – jonrsharpe Oct 31 '20 at 12:06
  • Hah. I'm sure you give some of the Huddersfuddlians too much credit (!) More than half of them voted for Brexit so it seems unlikely many of them would be familiar with Japanese calligraphy. All I meant was passive comprehension of JSON syntax (and certainly actively writing it) is elementary for someone who writes scripts and comprehends data-structures like `objects` and `arrays` but it's doubtless much less intuitive for someone who doesn't. – Rounin Oct 31 '20 at 12:11
  • More thinking (and probably final conclusions): I'm going to go with something similar to what I've outlined above, but instead of `loch^ness` and `loch`, I'm going to adopt the conventions of declarative HTML attribute syntax: `loch="ness"` and `loch`. – Rounin Oct 31 '20 at 12:27

1 Answers1

0

There is no syntax that would understand {a, b, c} when none of these a, b and c are defined variables. Moreover, it would not give a clue about the data types of these values, so in case of strings, you would need string values, not (undefined) variable references.

From comments, it seems you get user input in the form of a string, which would include a series of pairs and single values.

Here is a function that would parse such a string:

const toObject = str =>
    Object.fromEntries(
        str.split(" ")
           .map(pair => pair.split("^"))
           .map(([k, v]) => [k, v??k])
    );

let s = "name^John male height^185cm";
let obj = toObject(s);
console.log(obj);
trincot
  • 317,000
  • 35
  • 244
  • 286