Создание плагина jQuery: лучшие практики относительно видимости функций?

Я создаю плагин jQuery. До сих пор это хорошо работает, но у меня есть сомнение относительно способа, которым я делаю вещи:

jQuery.fn.myMethod = function() {
  return this.each(function(){
    MyScope.doSomething(jQuery(this).attr("id"));
  });
};

var MyScope = {

  // The functions contained in MyScope are extremely linked to the logic 
  // of this plugin and it wouldn't make a lot of sense to extract them

  doSomething: function(id){
    // something
    doSomethingElse(23);
    // some more code
    doSomethingElse(55);
  },

  doSomethingElse: function(someInt){
    // some code 
  }
};

Я использую MyScope для хранения всех моих "частных" функций. Я не хочу, чтобы пользователь смог пойти $("p").doSomething(), но я действительно должен использовать их.

Я мог переместить все в myMethod функция, но это создало бы 100, строки долго функционируют, и люди ненавидели бы меня в него.

Каковы лучшие практики в этой ситуации? Там какие-либо большие учебные руководства там расценивают это?

11
задан marcgg 11 June 2010 в 08:09
поделиться

3 ответа

Вы можете инкапсулировать свои функции, чтобы они делали то, что вы хотите, как, например, здесь:

jQuery.fn.myMethod = function() {
  return this.each(function(){
    doSomething(jQuery(this).attr("id"));
  });        
  function doSomething(id){
    //do something
  }
  function doSomethingElse(){
    // some code
  }
};

Вы можете посмотреть быструю демонстрацию здесь

"Я мог бы переместить все в функцию myMethod, но это создало бы функцию длиной в 100 строк, и люди возненавидели бы меня за это." .... почему?

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

Есть несколько стилей объявления, некоторые с одинаковым эффектом, вариант, который я привел - один из многих, но размещение вещей внутри myMethod - вполне разумный подход.


Чтобы быть более полным, вот еще одна альтернатива:

(function($) { 
    function doSomething(id){
      //do something, e.g:  doSomethingElse('bob');
    }
    function doSomethingElse(str){
      //some code
    }
    $.fn.myMethod = function() {
      return this.each(function(){
        doSomething(jQuery(this).attr("id"));
      });   
    };
})(jQuery);

Или еще одна:

(function($) { 
    var me = {
        doSomething: function(id){
         //do something, e.g:  this.doSomethingElse('bob');
        },
        doSomethingElse: function(str){
          //some code
        }
    };
    $.fn.myMethod = function() {
      return this.each(function(){
        me.doSomething(jQuery(this).attr("id"));
      });   
    };
})(jQuery);

Похожие статьи:

18
ответ дан 3 December 2019 в 03:17
поделиться

Нет ничего плохого в использовании большой функции только для создания новой области видимости. Следующее сохраняет doSomething и doSomethingElse приватными и позволяет избежать определения новых функций doSomething и doSomethingElse для каждого вызова myMethod, что произойдет, если поместить doSomething и doSomethingElse внутрь определения myMethod.

(function() {
  function doSomething(id) {
    // Something
  }

  function doSomethingElse() {
    // Something else
  }

  jQuery.fn.myMethod = function() {
    return this.each(function(){
      doSomething(this.id);
    });
  };
})();
6
ответ дан 3 December 2019 в 03:17
поделиться

Я бы поместил все в функцию jQuery.fn.myMethod, чтобы избежать возможных конфликтов пространства имен и сделать код более чистым. Этот шаблон также позволяет создавать частные методы, недоступные извне функции myMethod.

jQuery.fn.myMethod = function(options) {
  // Set up a "that" object, which can be referenced from anywhere inside this function
  var that = {};

  // If the plugin needs optional arguments, you can define them this way
  if (typeof(options) == 'undefined') options = {};
  that.options.option1 = options.option1 || 'default value 1';
  that.options.option2 = options.option2 || 'default value 2';

  that.init = function() {
    // psuedo-constructor method, called from end of function definition
  }

  that.doSomething = function() {
    // something
  }

  that.doSomethingElse = function() {
    // something else
  } 

  // Call init method once all methods are defined
  that.init();

  // Return the matched elements, to allow method chaining
  return jQuery(this);
}
4
ответ дан 3 December 2019 в 03:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: