# Prototype definition in object literal

**URL:** <https://es.discourse.group/t/prototype-definition-in-object-literal/768>\
**Category:** 💡 Ideas\
**Created:** [May 5, 2021, 2:02am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768 "2021-05-05T02:02:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Raised](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/raised/32/806_2.png) [@Raised](https://es.discourse.group/u/Raised)\
**Post date:** [May 5, 2021, 2:02am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/1 "2021-05-05T02:02:49Z")

</div>

The gist of the idea is to allow specifying the class/prototype of the object created via object literal syntax. Currently, any object created via object literal is an instance of built-in `Object` class:

```javascript
const example = {
  foo: 'bar'
};

```

so when you want to create a lightweight object, you write something like this:

```javascript
const example = Object.create(null);
example.foo = 'bar';

```

I can't tell how this affects [the property access optimization](https://mathiasbynens.be/notes/shapes-ics#optimizing-property-access), I believe either very minorly or it doesn't affect it at all. The idea is to use syntax like this to specify the class and properties of the object, created via object literal:

```javascript
//lightweight object
const example:null = {
  foo: 'bar'
};

//Normal object
const example1 = {
  foo: 'bar'
};

const example2:Object = {
  foo: 'bar'
};

//User-defined class
const example:MyClass = {
  foo: 'bar'
};

```

---

<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:** [May 5, 2021, 2:10am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/2 "2021-05-05T02:10:55Z")

</div>

This is actually possible since the early days of Javascript. It's just not a well-known feature and is a little unintuitive (so it could be nice to have better syntax for it)

But, you just have to set the special "` __proto__ `" property as you're creating the object, and that value will be set to the object's prototype.

For example:

```javascript
//lightweight object
const example = {
  __proto__ : null,
  foo: 'bar'
};

//User-defined class
const example = {
  __proto__ : MyClass.prototype,
  foo: 'bar'
};

```

MDN talks a little about it on this [page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer).

---

<div class="post-metadata">

**Author:** ![Raised](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/raised/32/806_2.png) [@Raised](https://es.discourse.group/u/Raised)\
**Post date:** [May 5, 2021, 2:31am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/3 "2021-05-05T02:31:50Z")

</div>

Yep. The gist of this post is all about the syntax. As far as I remember, the ` __proto__ ` property is not a part of the spec, so maybe it would make sense to come up with some standard syntax for this, with fewer magic properties?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [May 5, 2021, 2:52am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/4 "2021-05-05T02:52:19Z")

</div>

It’s absolutely part of the spec, since ES2015. It’s in the process of being moved out of Annex B, as well, so all implementations would be required to implement it (all do anyways).

---

<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:** [May 5, 2021, 3:16am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/5 "2021-05-05T03:16:11Z")

</div>

It might be hard to justify new syntax for it, since syntax already exists, and there's a high bar for adding new syntax to the language (to prevent it from becoming overly complicated). The current syntax doesn't really create any footguns either, it's just odd to use, especially since any google search about the ` __proto__ ` property will bring you with results talking about how getting or setting ` __proto__ ` on a property is deprecated (though they usually don't mention that ` __proto__ ` in an object literal isn't depracated).

I usually avoid ` __proto__ ` for that reason, and do one of these two solutions to create an object with a prototype.

```javascript
Object.assign(Object.create(null), { foo: 'bar' })
// or
Object.create(null, Object.getOwnPropertyDescriptors({ foo: 'bar' }))

```

These are a little more verbose, but I'm ok with that verbosity considering I don't do this kind of thing a ton. But I know some other Javascript coding styles make use of this kind of thing a lot more.

---

<div class="post-metadata">

**Author:** ![Raised](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/raised/32/806_2.png) [@Raised](https://es.discourse.group/u/Raised)\
**Post date:** [May 5, 2021, 3:48am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/6 "2021-05-05T03:48:52Z")

</div>

The only justifications that come to my mind are neater syntax and subtle (if any) improvements to object property access speeds, assuming that @ [theScottyJam](https://es.discourse.group/u/theScottyJam)'s example doesn't solve this problem.

Current ways to achieve the same look quite ugly, but I'm an artist, that's how I see it 👨‍🎨.

---

<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:** [May 5, 2021, 5:31pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/8 "2021-05-05T17:31:28Z")

</div>

That's certainly debatable.

I much prefer null prototypes, as there's much better support for working with objects than maps (both with syntax and with helper functions). Compare

```javascript
map[key] ??= 0
may[key]++

```

with

```javascript
if (!map.has(key)) {
  map.set(key, 0)
}
map.set(key, map.get(key) + 1)

```

I do, however, understand the hesitance with them, and understand when people choose to avoid them. But, I don't necessarily think the missing .toString() is a big enough reason to have _everyone_ shun them (though you may disagree, which is fine).

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [May 8, 2021, 3:44am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/9 "2021-05-08T03:44:28Z")

</div>

Nit: [`Map.prototype.emplace`](https://github.com/tc39/proposal-upsert) attempts to resolve that pretty elegantly.

```javascript
map.emplace(key, {
  insert: () => 1,
  update: x => x + 1
})

```

---

<div class="post-metadata">

**Author:** ![simonkcleung](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/simonkcleung/32/785_2.png) [@simonkcleung](https://es.discourse.group/u/simonkcleung)\
**Post date:** [May 8, 2021, 3:41pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/10 "2021-05-08T15:41:38Z")

</div>

I suggest a new method `Object.from(obj)`, which returns a new object having same keys and prototype of input object.

```javascript
const example = Object.create(null);
example.foo = 'bar';

const example1 = Object.from(example); // example1 and example having same 'Shape'
example1.foo = 'bar1';

```

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [May 9, 2021, 3:02am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/11 "2021-05-09T03:02:30Z")

</div>

You could get pretty far and call it a day:

```javascript
// Your proposed semantics
Object.from = source =>
    ({ __proto__ : Object.getPrototypeOf(source), ...source})

```

Given how niche that is, I'm not convinced it'll get to even stage 1, much less stage 4.

---

<div class="post-metadata">

**Author:** ![simonkcleung](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/simonkcleung/32/785_2.png) [@simonkcleung](https://es.discourse.group/u/simonkcleung)\
**Post date:** [May 9, 2021, 7:49am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/12 "2021-05-09T07:49:15Z")

</div>

Another reason of introducing Object.from(obj) is to provide a better way to maintain the 'Shape' (as mentioned at [the property access optimization](https://mathiasbynens.be/notes/shapes-ics#optimizing-property-access))of objects.  
e.g.

```javascript
const example1 = {
  foo: 'bar1'
};

const example2 = {
  foo: 'bar2'
};
// example1 and example2 are optimized

```

but later, you change one object

```javascript
const example1 = {
  foo: 'bar1',
  baz: 'baz'
};

const example2 = {
  foo: 'bar2'
};
// example1 and example2 are now not optimized

```

---

<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:** [May 9, 2021, 1:56pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/13 "2021-05-09T13:56:52Z")

</div>

I'm not sure I follow your thought process yet. Could you expound on how you would use Object.from() to help with property access optimization?

---

<div class="post-metadata">

**Author:** ![Raised](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/raised/32/806_2.png) [@Raised](https://es.discourse.group/u/Raised)\
**Post date:** [May 18, 2021, 4:18pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/14 "2021-05-18T16:18:55Z")

</div>

What about the performance of ` __proto__ `? I [tried to check the performance](https://jsben.ch/B8fDZ) vs `Object.create()`, but I struggle interpreting results (uncomment commented lines and ` __proto__ ` will show the best result).

It may be an off topic, but I'm curious why and when construction functions and `new` operator were preferred to syntax like this.

---

<div class="post-metadata">

**Author:** ![TitanNano](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/titannano/32/983_2.png) [@TitanNano](https://es.discourse.group/u/TitanNano)\
**Post date:** [August 28, 2021, 11:57am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/15 "2021-08-28T11:57:29Z")

</div>

> [@theScottyJam](#):
>
> It might be hard to justify new syntax for it, since syntax already exists, and there's a high bar for adding new syntax to the language (to prevent it from becoming overly complicated). The current syntax doesn't really create any footguns either, it's just odd to use, especially since any google search about the ` __proto__ ` property will bring you with results talking about how getting or setting ` __proto__ ` on a property is deprecated (though they usually don't mention that ` __proto__ ` in an object literal isn't depracated).

I think, exactly because of this, there should be a proper syntax for it... Almost no one knows about this and if you try to explain it to people they think it will make their code run slower and is deprecated.

Another thing is that `{ __proto__ : MyOtherObject }` is not recognized by any type inference engine out there except TernJS. Having a proper syntax that doesn't look like a hack, hopefully would improve this and get these sorts of tools to properly adopt it.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 28, 2021, 1:59pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/16 "2021-08-28T13:59:14Z")

</div>

I agree with @TitanNano here. The ` __proto__ ` syntax is a dirty legacy hack, and it totally is a footgun.

```javascript
> j = JSON.parse('{" __proto__":{"x":42}}');
{ [' __proto__']: { x: 42 } }

> o = { ...j };
{ [' __proto__']: { x: 42 } }
> Object.getPrototypeOf(o);
[Object: null prototype] {}

> o = Object.assign({}, j);
{}
> Object.getPrototypeOf(o);
{ x: 42 }

```

I was pondering different ways to replace the ` __proto__ ` quirk before finding this thread. So far I haven't been able to come up with a syntax I'd immediately like, but here are some alternatives for consideration:

```javascript
n = { null, ... };
// very concise, but has issues:
// 1) someone might read it as { "null": null }
// 2) only works for null

```

```javascript
n = { (null), ... };
o = { (Klas.prototype), ... };

```

```javascript
n = new null { ... }; // no line break before {
o = new Object.prototype { ... };

```

We could reuse the `extends` keyword:

```javascript
n = { extends null, ... };
o = { extends Klas.prototype, ... };
// or
o = { ... } extends Klas.prototype;
n = { ... } extends null;
// although I don't like the latter, because I want the prototype in front;
// otherwise there's little benefit over Object.setPrototypeOf({ ... }, P);

> Object.getPrototypeOf(n) === null
true
> Object.getPrototypeOf(o) === Klas.prototype
true

```

What I find unsatisfactory about these is that using `.prototype` after `extends` feels weird, and only starts making sense after you consider what `extends` does with classes:

```javascript
class A {};
class B extends A {};

> Object.getPrototypeOf(B) === A
true

```

---

<div class="post-metadata">

**Author:** ![TitanNano](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/titannano/32/983_2.png) [@TitanNano](https://es.discourse.group/u/TitanNano)\
**Post date:** [August 28, 2021, 2:10pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/17 "2021-08-28T14:10:04Z")

</div>

I personally would like this syntax, because it's similar to how other languages do struct instances.

```javascript
const Prototype = { a: 1, b: 2, doSomething() {} };
const a = Prototype { a: 3 };
const b = a { prop: true };

```

But I have no Idea if the existing ECMAScript grammar can accommodate it.

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [August 28, 2021, 2:38pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/18 "2021-08-28T14:38:58Z")

</div>

There [once was a proposal for a `<|` prototype operator](https://web.archive.org/web/20160404123540/http://wiki.ecmascript.org/doku.php?id=harmony:proto_operator) which did just that:

```javascript
const Prototype = { a: 1, b: 2, doSomething() {} };
const a = Prototype <| { a: 3 };
const b = a <| { prop: true }

```

In contrast to `{ __proto__ : …}`, it would work not just with object literals but also array, function or regex literals.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 28, 2021, 2:39pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/19 "2021-08-28T14:39:47Z")

</div>

> [@TitanNano](#):
>
> But I have no Idea if the existing ECMAScript grammar can accommodate it.

It can, but that would eliminate the possibility for any future `keyword {}` syntax, like e.g. [module blocks](https://github.com/tc39/proposal-js-module-blocks)

---

<div class="post-metadata">

**Author:** ![bakkot](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bakkot/32/22_2.png) [@bakkot](https://es.discourse.group/u/bakkot)\
**Post date:** [August 28, 2021, 10:57pm UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/20 "2021-08-28T22:57:08Z")

</div>

> [@lightmare](#):
>
> The ` __proto__ ` syntax is a dirty legacy hack, and it totally is a footgun.

The thing you're pointing at in that example is the ` __proto__ ` _setter_, not the ` __proto__ ` _syntax_.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 29, 2021, 7:32am UTC](https://es.discourse.group/t/prototype-definition-in-object-literal/768/21 "2021-08-29T07:32:51Z")

</div>

Thanks for clarification, I conflated the two things. ` __proto__ ` syntax in object literal is not the footgun. Still hate it, though.

[Next page](https://es.discourse.group/t/prototype-definition-in-object-literal/768.md?page=2)
