$.extend() with functions

17,254

Solution 1

Here's an example:

(function( $ ) {
  $.fn.pluginBar = function(options) {
      var settings = $.extend( {
          someEvent: function() {
              alert('default');
          }
      }, options);

      return this.each(function() {
          settings.someEvent();
      });
  };
})( jQuery );

$('div.foo').pluginBar({ 
    option1: 'red',
    someEvent: function() {
        alert('custom');
    }
});

If you don't specify someEvent when wiring up the plugin, the default one will be used.

Solution 2

In javascript, functions are first-class objects. Meaning, you can use functions like you would any other variable:

//making an anonymous function, and assigning it to a variable
var meep = function () {
    return 'meep';
};

//passing a function as a parameter
[ 'moop' ].map( meep ); //['meep']

//assigning it in an object literal
var weirdNoises = {
    'meep' : meep,

    'slarg' : function () {
        return 'slarg';
    }
};

weirdNoises.meep(); //'meep'
weirdNoises.slarg(); //'slarg'

//you can also return functions
function meeper () {
    return meep;
}
function slarger () {
    return function () {
        return 'slarg';
    };
}

//meeper returns a function, so the second () means "execute the function
// that was returned"
meeper()(); //'meep'
slarger()(); //'slarg'

As you can see, functions are just like any other value. So, you can define a default option that'll be a function, and override it like anything else.

$.fn.weirdNoise = function ( options ) {
    var defaults = {
        makeNoise : function () {
            return 'Rabadabadaba';
        },
        isSilly : true
    };

    return $.extend( defaults, options );
};

var raba = $( 'foobar' ).weirdNoise().makeNoise();
raba.makeNoise(); //'Rabadabadaba'
raba.isSilly; //true

var shaba = $( 'foobar' ).wierdNoise({
    makeNoise : function () {
        return 'Shabadabadoo';
    }
});
shaba.makeNoise(); //'Shabadabadoo'
shaba.isSilly; //true

A contrived example, but I think it illustrates the point.

Share:
17,254
Bojangles
Author by

Bojangles

Full stack web developer working with Node and React in Typescript and rather a lot of Rust.

Updated on June 25, 2022

Comments

  • Bojangles
    Bojangles about 2 years

    I'm writing a jQuery plugin that will need callback functions that are executed, for example, when an option is chosen from the <select> the plugin is applied to.

    I've seen plugins that allow you to define functions in the options you pass it, like this:

    $('div.foo').pluginBar({ 
        option1: 'red',
        someEvent: function() {
            // Do stuff
        }
    });
    

    I want to be able to define a default someEvent function in my plugin code, but if the user defines that function in the options they pass, it should overwrite the default function. Is this possible with $.extend(), or am I look in the wrong places?

    I've had a look at the plugin authoring tutorial, but I don't think it covers extending the default behaviour of functions anywhere. I've read things about using an init: function, but I'd rather just be able to define a function (inside the plugin namespace) and change it with the options passed to the plugin.

  • Taylor Evanson
    Taylor Evanson almost 10 years
    Just figured something out, thought i'd share -- to have 'div.foo' available to the someEvent function, pass "this" without quotes as a parameter. Fiddle - jsfiddle.net/taytayevanson/LY3K7