Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Second argument: proto, a la Object.create, or mapper, a la Array.from? #13

Closed
ljharb opened this issue Mar 12, 2018 · 12 comments
Closed

Comments

@ljharb
Copy link
Member

ljharb commented Mar 12, 2018

In particular, this would be useful to do Object.fromEntries(entries, null). It could reuse the same spec machinery as Object.create.

@bakkot
Copy link
Collaborator

bakkot commented Mar 12, 2018

This would have the opposite signature from Object.create, which would be somewhat annoying.

@ljharb
Copy link
Member Author

ljharb commented Mar 12, 2018

That’s true. Do you think there’s a reasonable way, that doesn’t have to use __proto__ to provide the [[Prototype]] without a second call?

@bakkot
Copy link
Collaborator

bakkot commented Mar 12, 2018

I don't think so, though I could easily be missing something obvious. I don't think a second call (or __proto__) is all that bad, though. Still might be worth adding something here; it just doesn't seem like it's absolutely required.

@ljharb
Copy link
Member Author

ljharb commented Mar 12, 2018

Definitely not required; but it feels like it'd be a win for optimizeability and code clarity.

@bathos
Copy link
Collaborator

bathos commented Mar 12, 2018

The current signature is appealing to me for a two reasons:

  • single arg functions play nicely with Array.prototype.map out of the box
  • it’s harder to draw a line re: what functionality is included if functionality goes beyond "turn these entries into a generic object"

The __proto__ prop was mentioned, but it seems like Object.setPrototypeOf would keep this clean and without much trouble, no?

const instance = Object.setPrototypeOf(Object.fromEntries(entries), prototype);

@ljharb
Copy link
Member Author

ljharb commented Mar 12, 2018

Certainly that's a solution; but that creates an object that extends Object.prototype, and then alters its prototype chain later - Firefox had a scary console warning about the performance impact of this for many years.

@bathos
Copy link
Collaborator

bathos commented Mar 12, 2018

If there were a second arg, one thing I’d suggest is that it seems it would cover more use cases if it were a target object to assign to, rather than a prototype to use: Object.fromEntries(entries, Object.create(null))

@ljharb
Copy link
Member Author

ljharb commented Mar 12, 2018

That might indeed be a better solution; but in that case, "from" might not be the proper word to use in the name - all the "from" methods generate a new object.

Regardless of our choice here, I'd hope that the default and most ergonomic usage creates a new object instead of mutating an existing one.

@ckknight
Copy link

@bathos' idea has merit:

It doesn't introduce a new way to create objects with non-Object.prototype __proto__s.

The second, optional argument is essentially the target. If target is not specified or evaluates to undefined, then Object.fromEntries would create its own target inheriting from Object.prototype.

The implementation is essentially:

Object.fromEntries = function (entries, target = {}) {
  for (const [key, value] of entries) {
    target[key] = value;
  }
  return target;
}

This does not solve the issue raised by attempting to use Object.fromEntries the callback for Array.prototype.map, as the second argument passed to Object.fromEntries would be a number.

One (gross) possibility would be to allow the user to call Object.fromEntries.call(Object.create(myProto), entries) and introspect on the this value within Object.fromEntries — this has a failing in that Object would be the this in the typical case.

I'm leaning more toward if you need a custom prototype for your object, perhaps a different function than vanilla Object.fromEntries is more appropriate.

@ljharb
Copy link
Member Author

ljharb commented Mar 12, 2018

I don't think we should be motivated by "passing it as a callback to map and friends"; that should be done in an arrow function to ensure explicit passing of args rather than implicit ones.

@ljharb
Copy link
Member Author

ljharb commented Apr 4, 2018

Another use case has popped up for a second argument in #7 - that it could be a mapper function, a la Array.from.

@ljharb ljharb changed the title Second argument a la Object.create? Second argument: proto, a la Object.create, or mapper, a la Array.from? Apr 4, 2018
@ljharb ljharb mentioned this issue Apr 14, 2018
4 tasks
@bakkot
Copy link
Collaborator

bakkot commented Jul 11, 2018

We've decided not to support a second argument.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants