# Object Initializer Constant Properties

**URL:** <https://es.discourse.group/t/object-initializer-constant-properties/864>\
**Category:** 💡 Ideas\
**Created:** [July 15, 2021, 6:28pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864 "2021-07-15T18:28:37Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [July 15, 2021, 6:28pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/1 "2021-07-15T18:28:37Z")

</div>

Does a proposal exist featuring constant properties at object initialization?

Something like:

```javascript
const a = {
  * "myPropName": "I am a constant",
  * ["my" + "other" + "prop"]: "I am also a constant",
}

```

(I used a star, but I would prefer something more sensible.) Equivalent to

```javascript
const a = {};
const constant = { writable:false, configurable:false, enumerable: true };
Object.defineProperty( a, "myPropName", { value: "I am a constant", ...constant } );
Object.defineProperty( a, "my" + "other" + "prop", { value: "I am also a constant", ...constant } );

```

I use object initialization to build name spaces for API modules, and there's a lot of Object.defineProperty involved just to be safe.  
I was hoping this was already on track after const appeared, but I haven't found it anywhere.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [July 15, 2021, 6:43pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/2 "2021-07-15T18:43:24Z")

</div>

Do you know about [Object.freeze()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)? Which will effectively make it so you can't reassign to any properties.

One option for syntax would be something like this:

```javascript
const a = {
  const "myPropName": "I am a constant",
  const ["my" + "other" + "prop"]: "I am also a constant",
}

```

const fits will here, since we're just indicating that we do not with that property to be re-assigned.

This seems like an interesting idea overall. As far as I know, there isn't any proposal like this.

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [July 15, 2021, 7:12pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/3 "2021-07-15T19:12:19Z")

</div>

I've used Object.freeze() in a few cases, but I've found it very frustrating. (No configurable properties, lots of getters / setters = unclear behaviors + boilerplate, bug-prone namespace nesting, have to re-call every time you create a copy, somehow track which parts of what are supposed to stay frozen, etc. )

I considered something like `a = { myConstProp :: {} }`, but I prefer that `const` syntax.  
Clarity over brevity here. The immutability should stand out.

I'm not qualified to have much to do with a proposal. But I could help if someone more experienced is interested.  
I'm not sure about its details. Would immutability survive destructuring?  
`b = { ...a }; //does b have some immutable properties?` (my guess: no)  
Can array literal entries be immutable?  
`c = [const id, 'a', 'b', 'c']` (guess: no)

---

<div class="post-metadata">

**Author:** ![senocular](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/senocular/32/642_2.png) [@senocular](https://es.discourse.group/u/senocular)\
**Post date:** [July 15, 2021, 7:12pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/4 "2021-07-15T19:12:57Z")

</div>

There's potential for [decorators](https://github.com/tc39/proposal-decorators/blob/f5e9f39fcd42ed7c6a675be9c7c6c1b6146f6c5a/EXTENSIONS.md#object-literal-and-property-decorators-and-annotations) to (eventually) facilitate this.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [July 15, 2021, 7:22pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/5 "2021-07-15T19:22:42Z")

</div>

Ah, yes, didn't think about decorators, that would make for a great solution to this problem. Decorators would also provide a clean way to set other property descriptors, like enumerability.

As for your questions @0X-JonMichaelGalindo - if we did have dedicated syntax, it would probably just be a shorthand for the writable property descriptor, so it'll behave exactly the same as your initial verbose example does. This means it would not survive destructuring, and it also means it's theoretically possible to make array properties non-writable (that's a weird concept - I feel like that would break a number of array functions) - I doubt there would be a reason to add syntax support for it, but if we piggy back off of decorators, then we might get that support, weather we like it or not. (After all, array elements are just numeric properties on the object).

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [July 15, 2021, 7:28pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/6 "2021-07-15T19:28:23Z")

</div>

Right! Thanks. Decorator meta-magic... Is there anything they can't do (\*eventually)?  
Definitely preferable to the limited case.

```javascript
a = { @static prop: "I will never change" }

```

Back to waiting, then. ⏳

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [July 15, 2021, 8:56pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/7 "2021-07-15T20:56:18Z")

</div>

> [@0X-JonMichaelGalindo](#):
>
> Is there anything they can't do

Since you asked... [Decorators](https://github.com/tc39/proposal-decorators) were on the [agenda for the TC39 meeting this week](https://github.com/tc39/agendas/blob/adbb26cafb9a4d0a682fd838442f11decd4768db/2021/07.md) and [this slide](https://slides.com/pzuraq/decorators-update-2021-07#/4) mentions what Decorators, in there current form, can and can not do.

> They _cannot_ :
> 
> - Replace with a different type of value
> - Add, remove, or replace values other than the decorated value

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [July 15, 2021, 9:04pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/8 "2021-07-15T21:04:47Z")

</div>

There is also [GitHub - tc39/proposal-record-tuple: ECMAScript proposal for the Record and Tuple value types. | Stage 2: it will change!](https://github.com/tc39/proposal-record-tuple)

For creating immutable Records. The current proposal is like this:

```javascript
const record = #{
  myPropName: "I am a constant"
};

Object.getOwnPropertyDescriptor(
  record,
  "myPropName"
); // { configurable: false, writable: false, value: "I am a constant" }

const secondRecord = #{
  ...record,
  aNewProp: 2 
};

```

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [July 16, 2021, 1:16am UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/9 "2021-07-16T01:16:57Z")

</div>

I very much approve of those artificial limitations on decorators! The (dangerously invisible) magic will be less prone to "leak" out of the line it's used. Fully compatible with my use cases.

I can't think of a specific use for immutable records at the moment. I foresee issues similar to freeze(). Still, I always want more tools to work with. I've found uses for everything else so far.

---

<div class="post-metadata">

**Author:** ![ethanlal04](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ethanlal04/32/918_2.png) [@ethanlal04](https://es.discourse.group/u/ethanlal04)\
**Post date:** [July 24, 2021, 4:28am UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/10 "2021-07-24T04:28:03Z")

</div>

Hi @0X-JonMichaelGalindo,

I love the concept. I would prefer to have `readonly` instead of const. Because const is usually used with variable declarations and not properties.

```javascript
const a = {
  readonly "myPropName": "I am a constant",
  readonly ["my" + "other" + "prop"]: "I am also a constant",
}

```

Unlike `Object.freeze()` this sets certain properties as `readonly` and not all.

If we do get a syntax like that we could take it to `class` level. (This is just like in `Typescript`)

```javascript
class Person {
  readonly name = "Ethan";
}

```

This could also save us from the boilerplate issue in OOP.

```javascript
class Person {
  readonly name;

  constructor(name) {
    this.name = name;
  }
}

// is the same as...

class Person {
  constructor(readonly name) {}
}

```

Thank you 😀.

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [July 24, 2021, 12:32pm UTC](https://es.discourse.group/t/object-initializer-constant-properties/864/11 "2021-07-24T12:32:43Z")

</div>

Yep, both good.  
Decorators will let you do whichever works best for your case. I prefer the decorators to the specific syntax because of how flexible they are.  
(It's the upcoming feature I'm most looking forward to!)  
Although, they're coming to classes first from what I understand, so it'll be a while before I can use them the way I want.

```javascript
const A = ({ @static id: UUID() });
const a = A();

```

```javascript
class A {
    @readonly id
    constructor() {
        this.id = UUID();
    }
}
const a = new A();

```
