Как получить имя класса Mootools изнутри - PullRequest
5 голосов
/ 08 мая 2009

Я бы хотел получить имя переменной класса.

var Poop = new Class({ 
    getClassName: function() { 
        return arguments.callee._owner.name;
    } 
});
var a = new Poop();
a.getClassName(); //want 'Poop'

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

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

Ответы [ 3 ]

8 голосов
/ 08 мая 2009

Нашел решение. Hash имеет функцию keyOf , которая выдаст мне имя переменной, которая содержит значение. Поэтому я сделал Hash of window, а затем спросил ключ конструктора класса.

var Poop = new Class({
    name: function() {
        var w = $H(window);
        return w.keyOf(this.constructor);
    }
});
var a = new Poop();
a.name(); // returns 'Poop'

Это, конечно, работает только потому, что я создаю классы в глобальном пространстве имен окна (как обычно в MooTools). Если вы создали классы внутри некоторого пространства имен, вам просто нужно вместо этого хэшировать это пространство имен.

Редактировать: Я написал о том, как использовать это решение и как заставить его автоматически работать в пространствах имен, для всех заинтересованных MooToolers.

2 голосов
/ 04 апреля 2012

Я столкнулся с проблемой с Extends, но нашел способ ее обойти:

var getClassNameFromKeys = function (obj, instance) {
        var i = 0, keys = Object.keys(obj);
        for (i; i < keys.length; i++) {
        if ('Ext' !== keys[i] && typeOf(obj[keys[i]]) === 'class' && instance instanceof obj[keys[i]]) {
                return keys[i];
            }
        }
    },
    Ext = new Class(),
    WhatsMyName = new Class({
        Extends: Ext
    }),
    whatsMyNameInstance = new WhatsMyName(),
    cName = getClassNameFromKeys(this, whatsMyNameInstance);

console.log(cName);

Вы можете избежать проверки имени расширения, если будете следовать шаблону примерно так:

var O = {},
    whatsMyNameInstance;

(function () {
    var SUBCLASS_KEYS;

    O.Ext = new Class({
        _className: null,
        getClassName: function () {
            var i = 0;

            SUBCLASS_KEYS = SUBCLASS_KEYS || Object.keys(O.subclasses);

            for (i; i < SUBCLASS_KEYS.length; i++) {
            if (this instanceof O.subclasses[SUBCLASS_KEYS[i]]) {
                    return SUBCLASS_KEYS[i];
                }
        }
        }        
    });
})();

O.subclasses = {};

O.subclasses.WhatsMyName = new Class({
    Extends: O.Ext
});

whatsMyNameInstance = new O.subclasses.WhatsMyName();

whatsMyNameInstance.getClassName();
0 голосов
/ 08 мая 2009

Я не думаю, что это возможно в Javascript из-за прототипно-ориентированной природы языка. Есть несколько вещей, которые вы можете сделать, чтобы определить, принадлежит ли объект существующему классу, который вы знаете, например:

if (a.constructor == Poop) {
     alert("This will work, but I don't really want any Poop.");
}

Однако на самом деле это не работает для определения класса неизвестного объекта. Есть и другие прототипы, которые вы можете сделать, чтобы проверить класс, который включает toString(), но они работают только для встроенных объектов, а не для пользовательских классов, и это недостаток прототипирования, который не характерен для MooTools.

Если вы посмотрите 5-е издание Javascript, The Definitive Guide , стр. 174, глава 9.7, там будет хорошее обсуждение. По сути, рекомендуется заполнить пользовательские классы свойством classname и переопределить метод базового класса объектов toString() по умолчанию, чтобы проверить это свойство при вызове его в пользовательском классе.

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