$ .extend () с функциями - PullRequest
       29

$ .extend () с функциями

6 голосов
/ 04 декабря 2011

Я пишу плагин jQuery, который будет нуждаться в функциях обратного вызова, которые выполняются, например, когда опция выбрана из <select>, к которому применяется плагин.

Я видел плагины, которые позволяют вам определять функции в передаваемых вами параметрах, например:

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

Я хочу иметь возможность определить функцию someEvent по умолчанию в моем коде плагина, но если пользователь определяет эту функцию в опциях, которые они передают, она должна перезаписать функцию по умолчанию. Возможно ли это с $.extend(), или я смотрю не в том месте?

Я посмотрел учебник по созданию плагинов *1011*, но я не думаю, что он охватывает расширение поведения по умолчанию функций в любом месте. Я читал кое-что об использовании функции init:, но я предпочел бы просто определить функцию ( внутри пространства имен плагина) и изменить ее с помощью параметров, передаваемых плагину.

Ответы [ 3 ]

15 голосов
/ 04 декабря 2011

Вот пример:

(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');
    }
});

Если вы не укажете someEvent при подключении плагина, будет использован вариант по умолчанию.

8 голосов
/ 04 декабря 2011

В JavaScript функции являются первоклассными объектами.Это означает, что вы можете использовать функции так же, как любую другую переменную:

//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'

Как видите, функции аналогичны любым другим значениям.Таким образом, вы можете определить опцию по умолчанию, которая будет функцией, и переопределить ее, как и все остальное.

$.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

Придуманный пример, но я думаю, что он иллюстрирует смысл.

0 голосов
/ 04 декабря 2011

Да, вы можете расширять объекты, которые имеют значения функций.

var originalFunction = function() { 
    alert( 'original' );
}

var a = { 
    foo: 'bar', 
    func: originalFunction 
};

var b = { 
    foo: 'baz', 
    func: function() { 
        alert( 'ok' ); 
    } 
};

var c = $.extend( {}, a, b );

c.func();    // alerts 'ok'

В JavaScript часто нет практической разницы между функциями и другими значениями, поэтому вы можете обращаться с функциями так же, как с другими объектами или типами данных.

...