Reputation: 971
I've seen quite a few tutorials or code examples where the developer used either Underscore's _.extend
method or Lodash's _.assign
method when a simply adding the property would have sufficed, it's always confused me, what is the benefit of using extend/assign instead of simply adding the property? There are plenty of times where I can see the benefits of using these methods, when adding multiple properties from another object for instance but most often I've seen it used as in the example below where I don't see any benefit.
Is there a benefit that I am not aware of for the following code instead of assigning the property?
http://tech.pro/tutorial/1734/building-decoupled-javascript-applications-with-postaljs
var Weather = function() {
this.channel = postal.channel( "weather" );
this.channel.subscribe( "fetch", this.fetch ).withContext( this );
};
_.extend(Weather.prototype, {
fetch: function( city ) {
$.ajax({
url: "http://openweathermap.org/data/2.1/find/name?q=" + city + "&units=imperial",
dataType: "jsonp",
success: _.bind(function( data ) {
this.channel.publish( "fetched", data.list[ 0 ] );
}, this )
});
}
});
For instance, couldn't the above code be rewritten thusly:
Weather.prototype.fetch = function(...){...}
Or is there a negative to this?
Upvotes: 6
Views: 1826
Reputation: 8308
In many cases, using Object.assign()
(or the library-provided equivalent) lets one write in a more functional style. Instead of using multiple statements just to add a single property to an object, you can do everything in one big expression.
Procedural:
function doThing(options) {
options.x = 5;
return _doThing(options);
}
Functional:
function doThing(options) {
_doThing(Object.assign(options, {x: 5}));
}
Also, if used with an empty object it idiomatically creates a shallow copy so as not to disturb a passed-in object in ways that might confuse the caller:
function doThing(options) {
_doThing(Object.assign({}, options, {x: 5}));
}
Upvotes: 0
Reputation: 11493
It exists for the same reason jQuery has $.extend
(including an npm port) and it has nothing to do with performance: to add one object's properies to a another object, thereby extending one with the other. Lodash' version allows for some more fine-grained control over the merge process using a customizer
function.
Extending objects has a couple of uses, of which one is stated by the jQuery developers on writing plugins:
An improvement we can, and should, make to the code above is to expose the default plugin settings. This is important because it makes it very easy for plugin users to override/customize the plugin with minimal code. And this is where we begin to take advantage of the function object.
// Plugin definition. $.fn.hilight = function( options ) { // Extend our default options with those provided. // Note that the first argument to extend is an empty // object – this is to keep from overriding our "defaults" object. var opts = $.extend( {}, $.fn.hilight.defaults, options ); // Our plugin implementation code goes here. }; // Plugin defaults – added as a property on our plugin function. $.fn.hilight.defaults = { foreground: "red", background: "yellow" };
In the above example you can clearly see that with are dealing with a preset object with properties, which needs to be extended or even overwritten by an unknown object with unknown properties, because that object is out of the plugin-developer's control
Sometimes we simply don't know which properties are on the extension object, sometimes it just makes things more readable and sometimes it is just to cumbersome to do it manually especially if you need a deep merge.
Another application is where you want to simulate a simple inheritance hierarchy:
// very trivial example:
var Super = { superFoo: function() {} };
var Sub1 = { sub1Foo: function() {} };
var Sub2 = { sub2Foo: function() {} };
$.extend(Sub1, Super) // now Sub1 has Super powers
$.extend(Sub2, Super) // now Sub2 has Super powers too
Upvotes: 1