Как объявить класс javascript с короткими именами функций и назначить позднее длинное имя класса? - PullRequest
3 голосов
/ 10 февраля 2010

Позвольте мне объяснить, это касается отображения исходного кода класса в IDE. У меня всегда есть только один класс на файл. Класс объявлен так в файле mod1.js:

MYGLOB.MOD1.ClassXy = function () {
  //constructor, do somothing
}

MYGLOB.MOD1.ClassXy.prototype.memberfunc1 = function () {
  //member function 1, do somothing
}

(В реальном классе гораздо больше функций, таких как memberfunc1.)

Но в разных IDE и редакторах ширина списка функций теперь очень велика. Я хочу, чтобы списки функций отображали только последнюю часть имени функции (само имя функции).

Как насчет этого:

ClassXy = function () {
  //constructor, do somothing
}

memberfunc1 = function () {
  //member function 1, do somothing
}

MYGLOB.MOD1.ClassXy = ClassXy;
MYGLOB.MOD1.ClassXy.prototype.memberfunc1 = memberfunc1;

Хорошо отображается в списке функций. Это не беспокоит, что есть 2 длинных назначения в нижней части файла. Но у меня загрязнено глобальное пространство имен. Как это сделать, не влияя на глобальное пространство имен с помощью глобальных «ClassXy» и «memberfunc1»? (MYGLOB.MOD1.ClassXy в порядке.)

Можно ли как-то сделать это с паренсом / закрытием или что вы предлагаете? И сохранить эффект наличия чистого списка функций в IDE, хотя бы первая часть списка функций показывает мне функцию-член с их короткими именами?

Пожалуйста, не предлагайте разные IDE или редакторы, речь не идет о выборе другого редактора кода. Пожалуйста, откройте другой вопрос самостоятельно, если вы хотите это обсудить. Этот вопрос о javascript и классах.

Может быть, это простая вещь, но я новичок в javascript.

Ответы [ 2 ]

1 голос
/ 10 февраля 2010

Это будет немного зависеть от возможностей редакторов, которые вы используете, но шаблон модуля может быть полезен для этого (и для предотвращения глобального загрязнения пространства имен в целом). Я начну ответ, предполагая, что вы делаете это, когда определяет ваших классов (действительно объектов), но в конце есть примечание об использовании сокращенных псевдонимов, когда потребляет классов (объектов) ) а также.

Базовый пример шаблона модуля

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);
0 голосов
/ 10 февраля 2010

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

Fs = new Object();
Fs['ClassXy'] = function() {
    this.time = new Date();
    alert("From ClassXy: " + this.time);
};

Fs['memberfunc1'] = function() {
    alert("From memberfunc1: " + this.time);
};

ClassXy                       = Fs['ClassXy'];
ClassXy.prototype.memberfunc1 = Fs['memberfunc1'];

const aCX1 = new ClassXy();
aCX1.memberfunc1();

Пример кода выше работает.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...