Создание плагина jQuery: лучшие практики относительно видимости функций? - PullRequest
11 голосов
/ 10 июня 2010

Я создаю плагин 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 строки люди будут ненавидеть меня за это.

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

Ответы [ 3 ]

18 голосов
/ 10 июня 2010

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

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);

Статьи по теме:

6 голосов
/ 10 июня 2010

Нет ничего плохого в использовании большой функции просто для создания новой области видимости. Следующее сохраняет 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);
    });
  };
})();
4 голосов
/ 10 июня 2010

Я бы поместил все внутри функции 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...