Skip to content

Instantly share code, notes, and snippets.

@rwaldron
Forked from ericf/gist:3751340
Created September 19, 2012 18:43
Show Gist options
  • Select an option

  • Save rwaldron/3751415 to your computer and use it in GitHub Desktop.

Select an option

Save rwaldron/3751415 to your computer and use it in GitHub Desktop.
ES6 Object.assign( target, source ) as a native options object merging pattern.
let defaults = { file: null };
function foo(options) {
// Merging defaults and options objects in ES6
options = [ defaults, options ].reduce(Object.assign, {});
}
foo({ file: "happy.md" });
/*
Object.assign( target, source )
When passed as the callback to reduce, the params are bound as:
function( prev, value ) {}
*/

Object.assign( target, source )

Object.assign( target, source )

Rough spec expectations:

  • Only enumerable own properties of source
  • Invoke [[Get]] on property list derived from source, for each property in list [[Put]] on target
  • private names are not copied
  • unique names are copied
  • super mechanism (rebind super)… AWB To determine needs
  • Returns modified "target"
@csnover

csnover commented Dec 8, 2012

Copy link
Copy Markdown

I really feel like if this function doesn’t accept more than one source object argument, people are going to keep writing alternatives for it so it might as well not even be in the spec. Using Array.prototype.reduce just doesn’t cut it when it comes to the sort of expressibility people have come to expect from jQuery.extend, dojo.mixin, etc.

@jdalton

jdalton commented Dec 15, 2012

Copy link
Copy Markdown

I've implemented _.extend and _.defaults to follow Object.assign and iterate only own properties in Lo-Dash v0.10.0+. The only real issue I've seen is in @tbranyen's backbone.layoutmanager which had to implement a custom augment method to normalize the behavior of Underscore/Lo-Dash because there was code that passed objects with inherited properties to _.extend.

Btw +1 on allowing multiple sources (_.extend and _.defaults allow it too).

@robotlolita

Copy link
Copy Markdown

I agree that Object.assign should be variadic. It makes not that much sense being non-variadic and forcing the users to jump through hoops to compose basic use cases when it could easily maintain the composition properties it already has and cover those use cases by just allowing multiple sources.

Why? It's easier to follow for static arguments (and doesn't mess with ASI!):

Object.assign({}, default, options)

// vs.

[ default, options ].reduce(Object.assign, {})

It can cover non-static arguments through both the familiar .apply and the Array::reduce:

Object.assign.apply(null, [{}].concat(xs))

// vs

xs.reduce(Object.assign, {})

On another note, I do find assign to have strong associations with replacing values and working with a single key/value association. I don't think define describes the operation being carried out that well either, but right now I can't think of any better names =/

@killroy42

killroy42 commented Jul 24, 2016

Copy link
Copy Markdown

Wouldn't this make more sense: (I might be late to this discussion)
constructor({opt1, opt2, opt3} = {opt1: def1, opt2: def2, opt3: def3}) { ... }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment