# Ability to access property \*without\* prototype inheritance

**URL:** <https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152>\
**Category:** 💡 Ideas\
**Created:** [September 23, 2024, 5:51am UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152 "2024-09-23T05:51:46Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![trusktr](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/trusktr/32/183_2.png) [@trusktr](https://es.discourse.group/u/trusktr)\
**Post date:** [September 23, 2024, 5:51am UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/1 "2024-09-23T05:51:46Z")

</div>

Sometimes you want to access an own property only.

For example, sometimes you want to do the equivalent of

```js
obj[key]

```

but _without_ the prototype lookup happening so that

- if the property is not an own property, then the result will be undefined (do not get the value from prototype)
- if the property is an own property, then it returns the value

This would be especially useful when using Symbols as an alternative to WeakMap, for example, where we want to associate state per object reference and not have it shared with multiple objects via prototype.

```js
const something = Symbol()

const obj = {}

obj[something] = 123

const obj2 = { __proto__ : obj}

obj2[something]

```

In that sample, `obj2[something]` returns `123` because it looks the property up on the prototype (obj). However, in some cases, the desire is no to have inheritance, and for it to return undefined. Currently, it would require doing this:

```js
Object.getOwnPropertyDescriptor(obj, something).value

```

which will return undefined if the property is not obj2's own property.

## Syntax?

Maybe some syntax could enable this?

```js
own obj2[something]

```

or

```js
obj2.%something

```

?

## special non-syntactic symbol?

If syntax is not doable, maybe a special Symbol type could prevent the engine from doing prototype lookup and we could at least do this with the special Symbol, bit not string properties? F.e.:

```js
const something = Symbol.own()

// ...same as before...

obj2[something] // does not do prototype lookup, returns undefined 

```

---

<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:** [September 23, 2024, 3:37pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/2 "2024-09-23T15:37:53Z")

</div>

This is a somewhat obscure thing to do, which means it doesn't warrant syntax or other magic, and given that constraint I think `Object.hasOwn(x, k) ? x[k] : void 0` is sufficient.

---

<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:** [September 23, 2024, 3:59pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/3 "2024-09-23T15:59:20Z")

</div>

I don't think it's all that obscure - any use of null objects could instead be a normal object only used with a "get own" semantic, as well as matching well with Object.assign and object spread only using own keys - but I agree there's not currently enough of a compelling case to warrant syntax (and i'm not a fan of anything that isn't simple sugar over that oneliner)

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/trusktr/32/183_2.png) [@trusktr](https://es.discourse.group/u/trusktr)\
**Post date:** [September 24, 2024, 7:04am UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/4 "2024-09-24T07:04:11Z")

</div>

Ah, yes. `hasOwn`. Forgot about that.

Huh, the `hasOwn` version is the slowest, even slower than getting the own descriptor! [Benchmark: WeakMap vs Symbol 2 - MeasureThat.net](https://www.measurethat.net/Benchmarks/Show/32046/0/weakmap-vs-symbol-2)

A syntax feature would make this the fastest (property lookup being faster than WeakMap.get in the benchmark)

---

<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:** [September 24, 2024, 7:44am UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/5 "2024-09-24T07:44:25Z")

</div>

That may be that `Object.hasOwn` isn't optimized as it's relatively new. [lib: use `ObjectHasOwn` instead of alternatives by anonrig · Pull Request #54710 · nodejs/node · GitHub](https://github.com/nodejs/node/pull/54710#issuecomment-2325374488)

---

<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:** [September 24, 2024, 7:50am UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/6 "2024-09-24T07:50:49Z")

</div>

I think there is a typo in the benchmark it has:

`Object.hasOwn(sy)` instead of `Object.hasOwn(to1, sy)`

---

<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:** [September 24, 2024, 9:04pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/7 "2024-09-24T21:04:54Z")

</div>

I don't thing I'd want syntax for this either, but at least another function to go with Object.hasOwn() would be nice.

Object.getOwn(obj, key)

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/trusktr/32/183_2.png) [@trusktr](https://es.discourse.group/u/trusktr)\
**Post date:** [September 24, 2024, 11:48pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/8 "2024-09-24T23:48:32Z")

</div>

> [@aclaymore](#):
>
> I think there is a typo in the benchmark

Oops! Fixed: [Benchmark: WeakMap vs Symbol 3 - MeasureThat.net](https://www.measurethat.net/Benchmarks/Show/32057/0/weakmap-vs-symbol-3)  
It is still slowest at the moment.

> [@theScottyJam](#):
>
> Object.getOwn(obj, key)

That could be useful. I suppose then `Object.setOwn(...)` would skip inheritance too, overriding any prototype accessor with a value descriptor.

---

<div class="post-metadata">

**Author:** ![mhofman](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@mhofman](https://es.discourse.group/u/mhofman)\
**Post date:** [September 25, 2024, 5:59am UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/9 "2024-09-25T05:59:40Z")

</div>

> [@trusktr](#):
>
> I suppose then `Object.setOwn(...)` would skip inheritance too, overriding any prototype accessor with a value descriptor.

Is the expectation to call a setter if its an own setter, and define a value property if no property exists?

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/trusktr/32/183_2.png) [@trusktr](https://es.discourse.group/u/trusktr)\
**Post date:** [September 25, 2024, 5:04pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/10 "2024-09-25T17:04:14Z")

</div>

@mhofman not in particular. I've been maintaining decorators for some years now, and what I find is that when implementing meta code, I usually don't want inheritance.

For example just last night I adopted the new standard `context.metadata` to track data for getters/setters, and I needed to block inheritance on metadata to achieve my specific goal:

> <https://github.com/lume/classy-solid/blob/0ad095ccbca486d21552c3382891988689d39366/src/decorators/signal.ts#L119>

Otherwise I would accidentally override features for a base class.

In various meta programme cases, I need to skip inheritance like that, so that a subclass feature _overrides_ anything from a base class feature.

Here's another example where I need to ensure subclass has an own prop:

> <https://github.com/lume/element/blob/c372a81203723f55f514e8077336913811febcd2/src/attribute.ts#L124>

Or here:

> <https://github.com/lume/element/blob/c372a81203723f55f514e8077336913811febcd2/src/attribute.ts#L190>

(don't worry about the impl, I'm refactoring it yet again now that standard decorators allow some new things hehe)

This (and basically anything with decorators) is meta programming, and that's where I usually run into the need. Maybe not to common for average code where people may only be writing classes and _using_ the decorators.

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/trusktr/32/183_2.png) [@trusktr](https://es.discourse.group/u/trusktr)\
**Post date:** [September 25, 2024, 5:09pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/11 "2024-09-25T17:09:17Z")

</div>

With some syntax, this would be doable:

```js
foo.%bar // get own
foo.%bar = {} // set own
foo.%bar ??= {} // set own if does not exist 

```

getOwn/setOwn could be nifty.

```js
const foo = Object.hasOwn(o, 'foo') ? Object.getOwn(o, 'foo') : Object.setOwn(o, 'foo', [])

```

where setOwn returns the set value (to match semantics of `=` returning the set value)

But there are bigger fish to fry.

---

<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:** [September 25, 2024, 5:15pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/12 "2024-09-25T17:15:19Z")

</div>

My expectation would be that "get own" and "set own" would do exactly the same thing as it would do if you'd set the [[Prototype]] to `null` right before doing the operation.

---

<div class="post-metadata">

**Author:** ![mhofman](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@mhofman](https://es.discourse.group/u/mhofman)\
**Post date:** [September 25, 2024, 9:56pm UTC](https://es.discourse.group/t/ability-to-access-property-without-prototype-inheritance/2152/13 "2024-09-25T21:56:25Z")

</div>

Right, so I was actually wrong earlier. `setOwn` would call an existing own setter if it exists, or define the property if no own accessor property exists. It would fail if a own getter only property existed.

It's all fairly consistent, but possibly too niche for a new standard API. However while getOwn is pretty straightforward in userland, setOwn is harder to get right (highlighted by the mistake I made). That might motivate the existence of such standard helpers?
