Создание плагина 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 для хранения всех моих функций "private". Я не хочу, чтобы пользователь мог идти $("p").doSomething()
, но мне нужно их использовать.
Я мог бы перемещать все в функции myMethod
, но это создавало бы 100-строчную функцию, и люди меня ненавидят.
Какие лучшие практики в этой ситуации? Есть ли отличные учебники по этому поводу?
Ответы
Ответ 1
Вы можете инкапсулировать свои функции, чтобы делать то, что хотите, например:
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);
Статьи по теме:
Ответ 2
Нет ничего плохого в использовании большой функции только для создания новой области. Следующее сохраняет doSomething
и doSomethingElse
private и избегает определения новых функций 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);
});
};
})();
Ответ 3
Я бы поставил все внутри функции 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);
}