3

I'm seeing a lot of this these days:

function Dog () {
    this.name = 'Fido';
}

_.extend(Dog.prototype, {
    bark: function() {
        return 'BARK, BARK!'
    },
    soilChothingWithDirtyPaws: function () {
        // Some intricated logic here
        return 'There, I did it!';
    }
});

But is the result different from the code below?

function Dog () {
    this.name = 'Fido';
}
Dog.prototype = {
    bark: function() {
        return 'BARK, BARK!'
    },
    soilChothingWithDirtyPaws: function () {
        // Some intricated logic here
        return 'There, I did it!';
    }
}

I know what underscore's extend function is supposed to do, but I don't really get the point of doing this in the object's prototype - when you could do this with plain old vanilla JS, that means, I can't see why a man in the middle is needed here. I wonder if I'm missing something really neat.

Does that bring any good at all?

It would be really nice if somebody clear things out. Thanks a lot!

darksoulsong
  • 13,988
  • 14
  • 47
  • 90
  • possible duplicate of [Defining a Javascript prototype](http://stackoverflow.com/questions/17474390/defining-a-javascript-prototype) – Bergi Apr 01 '14 at 17:23
  • @Bergi It's not a duplicate at all, because the aforementioned question doesn't involve underscore's _.extend() method. My question is if is there any benefit of using it instead of plain prototypes and not about how to use js prototypes. – darksoulsong Apr 01 '14 at 17:57
  • Well, I though you knew that `_.extend(Dog.prototype, {bark: function() {…}});` is equal to `Dog.prototype.bark = function() {…};`. I even mentioned `extend` in my answer there (which is about extending vs overwriting prototypes, not about underscore extend). – Bergi Apr 01 '14 at 18:02

1 Answers1

6

_.extend is defined like this,

_.extend = function(obj) {
    each(slice.call(arguments, 1), function(source) {
        if (source) {
            for (var prop in source) {
                obj[prop] = source[prop];
            }
        }
    });
    return obj;
};

All it does is, iterate over the attributes of all the elements from the argument at index 1 till the end and add it to the first argument passed to it.

So, technically, what you have done will have the same effect, but with one subtle difference.

When you use _.extend, you are augmenting the Dog.prototype object, when you assign to it (like in your second example), you are replacing the Dog.prototype object with some other object.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • 2
    The difference isn't that subtle, `Dog.prototype.constructor` will have a different value! – Bergi Apr 01 '14 at 17:24