Это будет немного зависеть от возможностей редакторов, которые вы используете, но шаблон модуля может быть полезен для этого (и для предотвращения глобального загрязнения пространства имен в целом). Я начну ответ, предполагая, что вы делаете это, когда определяет ваших классов (действительно объектов), но в конце есть примечание об использовании сокращенных псевдонимов, когда потребляет классов (объектов) ) а также.
Базовый пример шаблона модуля
var MYGLOB.MOD1.ClassXy = (function() {
// Define your constructor function
function ClassXy() {
}
// Define your member functions
function memberfunc1() {
}
// Put your member functions on the prototype
ClassXy.prototype = {
memberfunc1: memberfunc1
};
// Return the constructor function to assign it to the MYGLOB.MOD1 object
return ClassXy;
})();
Там я заменил на prototype
; вы можете просто добавить к нему вместо этого, и в этом случае я предлагаю иметь где-нибудь вспомогательную функцию, которая делает поверхностное копирование свойства:
function shallowCopy(dest, src) {
var name;
for (name in src) {
// Depending on your needs, you may want to check
// src.hasOwnProperty(name) here and only copy it
// when that's true
dest[name] = src[name];
}
}
И затем заменить присвоение prototype
выше следующим:
shallowCopy(ClassXy.prototype, {
memberfunc1: memberfunc1
});
Именованные функции
Помимо прочего, использование этого шаблона означает, что вы используете именованные функции , а не анонимные. Это помогает вашим инструментам (особенно отладчикам). Этот формат создает анонимную функцию и назначает ее свойству объекта:
MyObject.functionName = function() { ... }; // Not ideal
Принимая во внимание, что если вы используете шаблон модуля, вы можете объявить свои функции обычным образом, а затем назначить их свойствам позже (см. Выше); таким образом, у них есть имен , которые отладчики могут показывать вам в стеках вызовов и т. д.
Функции частных утилит
Шаблон также предоставляет хороший способ использования служебных функций (или данных всего класса) классом без необходимости делать их общедоступными вообще - не в функции конструктора, не в ее прототип, а не в случаях. Например, вот выше с частной утилитой:
var MYGLOB.MOD1.ClassXy = (function() {
// Define your constructor function
function ClassXy() {
}
// Define your member functions
function memberfunc1() {
// Call our utility function. In this form, be aware that
// within the utility, `this` will *not* be set within
// the utility
utility('bar');
// Alternate form if you want to call `utility` as though it
// were an instance member function; within the utility, it
// can refer to `this` and have it mean the same thing it
// means here in `memberfunc1`
utility.call(this, 'bar');
}
// A utility function. This is entirely private to the class,
// we don't make it a property of anything and so it's never
// visible outside the closure
function utility(foo) {
alert("foo = " + foo);
}
// Put your member functions on the prototype
shallowCopy(ClassXy.prototype, {
memberfunc1: memberfunc1
});
// Return the constructor function to assign it to the MYGLOB.MOD1 object
return ClassXy;
})();
Использование помощника
Выше может показаться немного неуклюжим на первый взгляд, но нет никаких причин, по которым вы не можете создавать помощников, чтобы упростить определение классов таким способом. Это то, что я сделал; используя мой помощник, я бы определил ваш пример так:
MYGLOB.MOD1.ClassXy = Class.defineClass(function() {
// Takes the place of the constructor function; defining it is
// optional, though, if you don't need to do anything when created
function initialize() {
}
// A member function
function memberfunc1() {
}
// Export our public symbols
return {
initialize: initialize,
memberfunc1: memberfunc1
};
});
Вы можете получить помощника (и причины этого) из моего блога по теме.
Использование многословных API
Этот же шаблон можно включить, если вы хотите потреблять API, который требует много времени: просто определите функцию, передайте длинные вещи как аргументы и используйте Имя аргумента вместо:
(function(xy) {
// Use the member function; within this closure, xy = MYGLOB.MOD1.ClassXy
xy.memberfunc1();
})(MYGLOB.MOD1.ClassXy);