Object.assign with several source objects
[target, s1, s2, s3].reduce(function(p, c){
return Object.assign(p, c);
});
P.S. actually, that is the equivalent of [target, s1, s2, s3].reduce(Object.assign);
but I was not sure it accept extra arguments too
It's now or never. I agree multiple sources are useful enough to do now; I don't see a different third parameter that would be precluded by deciding this. But others may disagree.
Interestingly, if multiple arguments are not added now, they may never be possible, since there will be so much [a, b, c].reduce(Object.assign)
code in the wild that implicitly passes an index as the third parameter and the whole array as the fourth parameter.
FWIW I don't see any other usage for extra arguments neither
Your insight about Andreas's reduce example seals the deal for me.
true ... as true is for anything that will ever be passed to reduce that accept just 2 arguments. Handy in a way, blocking progress in others.
Object.assing(target, ...[multSources]);
wins to me
the alternative is that the second argument expects an array of 1 to n source objects. This works with reduce and leaves way clear for future 3rd argument (eg deep copy boolean)
Mandatory array-of-parameters is an anti-pattern, given spread. Even if
the allocation costs nothing, the obligatory [
and ]
around the most
common (singleton) case is a eye-killer.
We don't want indefinite future-proofing for argument extension, BTW. We always get in trouble trying to do that, because real code passes trailing args. What we want are fixed arity functions that we never extend, and variadic functions that are variadic from the get-go.
I think deep copy is not ever happening, in the same vein. Just say no, KISS, don't leave too much open -- it won't actually pan out.
On Tue, Dec 17, 2013 at 8:17 PM, Brendan Eich <brendan at mozilla.com> wrote:
It's now or never. I agree multiple sources are useful enough to do now; I don't see a different third parameter that would be precluded by deciding this. But others may disagree.
A third Properties argument that matches the second Properties argument to Object.create() and Object.defineProperties
class Cycle {
constructor(details) {
Object.assign(this, details, {
wheels: {
value: details.type === "tricycle" ? 3 : 2,
configurable: false,
writable: false
}
});
}
}
var trike = new Cycle({
color: "red",
type: "tricycle"
});
... Which doesn't break the reduce pattern since the index would effectively be meaningless in that context, ie. Object.getOwnPropertyNames(Object(1)).length === 0;
Anyway...I had originally pushed for Object.assign with multiple sources and dropped it when consensus seemed to hinge on "one target, one source". The third Properties argument is compelling and doesn't prevent using Object.assign as a primitive mechanism for library code to build on top of.
Rick I tend to aree with you if not that the second argument of Object.create has basically reached zero libraries and popularity out there due un-shimmable and "boring to write" common/usual properties.
In this very specific case it would be inconsistent with the previous argument too since that won't be checked through getOwnPropertyNames in any case ... you know what I mean?
I can't see a better use for extra arguments than multiple extensions. This
is how current libraries implement it and we expect to replace it with
Object.assign
. In case Object.assign
accepts only two arguments I think
this snippet will be everywhere
Object.assign(Object.assign({}, defaultParams), userParams);
// or
[ {}, defaultParams, userParams ].reduce(Object.assign);
I think using properties descriptor at Object.assign
will be a mix of
concepts, and a pattern I see a lot less than _.extend
, and we'll be able
to do it anyway
Object.defineProperties(Object.assign({}, properties), descriptors);
// or
Object.assign(Object.create(something, descriptors), properties);
And deep copy doesn't look like an option for me, as Brendan said it adds so much complexity for an edge case.
I think accepting several source objects like _.extend
, $.extend
and
angular.extend
would be the more practical option.
Are we really doing Object.assign for ES6? We postponed Object.mixin so we should probably postpone Object.assign too.
Yes, this was originally accepted on it's own merit, before
Object.define
/mixin
. Object.assign
is already widely implemented in many
forms (under different names) gist.github.com/rwaldron/3744794
Two months ago, I have expressed the wish that Object.assign
could accept several source objects. It seems to me that the idea was mostly positively received (although I may be biased). However, there don't seem to have been any decision taken on that subject.
What now? It would be nice if a decision could be taken.
My intention is to present an agenda item at the next face to face.
+1
It's very common use case. Recently I switched to Object.assign in my utils
lib, and needed to replace one function with two: assign
and
assignMultiple
. It doesn't look as nice now.
There are a lot of use cases for that, also one to do non-destructive merge (via @pornelski):
Object.assign({}, foo, bar);
Tonight, when playing with ES6’s new functions, I was wishing that
Object.assign
could accept severalsource
objects:Object.assign(target, source1, source2, ...) // equivalent to `Object.assign(Object.assign(Object.assign(target, source1), source2), ...)`
My use case: I have several objects, used as dictionaries, coming from different sources, and I want to merge them together. For example:
Any thoughts?