3

I was searching for a proper way of extending bootstrap plugin, and found this answer: https://stackoverflow.com/a/12689534/1276032

What troubles me, is the last section - initialization overriding. Copied code below:

// override the old initialization with the new constructor
$.fn.modal = $.extend(function(option) {

    var args = $.makeArray(arguments),
        option = args.shift();

    return this.each(function() {

        var $this = $(this);
        var data = $this.data('modal'),
            options = $.extend({}, _super.defaults, $this.data(), typeof option == 'object' && option);

        if ( !data ) {
            $this.data('modal', (data = new Modal(this, options)));
        }
        if (typeof option == 'string') {
            data[option].apply( data, args );
        }
        else if ( options.show ) {
            data.show.apply( data, args );
        }
    });

}, $.fn.modal);

I don't understand why $.extend is used in this case - does it have some effect that I don't see? If I execute this code:

var f1 = function(){console.log(1);};
var f2 = function(){console.log(2);};
var f2 = $.extend(f1,f2);
f2();

then only 1 is printed to the console, and f1 equals f2. So it seems simple assingnment would do,

$.fn.modal = function(option) {...}

but maybe I miss something...

Community
  • 1
  • 1
Arek Dygas
  • 103
  • 9

1 Answers1

0

You need to change this:

$.fn.modal = $.extend(function(option) {
    // your code ...
}, $.fn.modal);

for this:

$.extend($.fn.modal, function(option) {
    // your code ...
});

TL;DR

$.extend(a, b) copies the content of b on a (modifying it's content), and if any repeated, then the property of b remains. Also, it returns the value of a.

So, If you have this:

hello    = { unique_on_hello: 'hola',  message: 'hello message' }
world    = { unique_on_world: 'mundo', message: 'WORLD MESSAGE' }
response = $.extend(hello, world)

The values of each one will be:

hello    // {unique_on_hello: "hola", message: "WORLD MESSAGE", unique_on_world: "mundo"}
world    // {unique_on_world: "mundo", message: "WORLD MESSAGE"}
response // {unique_on_hello: "hola", message: "WORLD MESSAGE", unique_on_world: "mundo"}

So, if you do f2 = $.extend(f1,f2); is the same as:

$.extend(f1, f2) // Copy properties of f2 to f1
f2 = f1

Source: https://api.jquery.com/jquery.extend/

Giovanni Benussi
  • 3,102
  • 2
  • 28
  • 30
  • 1
    Thx for the reply. I know how $.extend work for objects. The clue of my question was related to a case, when functions are passed as its arguments. Your suggestion (changing `f2 = $.extend(f1,f2)` to `$.extend(f2,f1)`) doesn't really answer my question, because I don't want to change anything - I only want to learn, why this code was a part of an accepted, and actually quite upvoted answer (currently 32 upvotes). And besides - changing this code still doesn't extend anything. Result is always function from first argument. – Arek Dygas Sep 28 '16 at 15:45