Динамически определяемые имена функций в JavaScript? - PullRequest
1 голос
/ 01 марта 2012

Это то, чего я пытаюсь достичь.Вот существующий фрагмент кода -

function PartMetaData(dataElement) {
this.metaData = new MetaData(dataElement);

this.getDescription = function () {
    return this.metaData.getElement("data-part-description");
};

this.getLength = function () {
    return this.metaData.getElement("data-part-length");
};

this.getWidth = function () {
    return this.metaData.getElement("data-part-width");
};

this.getHeight = function () {
    return this.metaData.getElement("data-part-height");
};

this.getWeight = function () {
    return this.metaData.getElement("data-part-weight");
};
}

Теперь посмотрим на связь между именем функции и именем атрибута - это очень похоже на повторяющийся код, которого можно избежать.Это то, что может быть достигнуто?Есть ли способ разрешить «любой» вызов функции для объекта и определить, что делать в зависимости от имени функции?

например, что-то вроде (синтаксис составлен, я не знаю, если что-то вродеэто существует в Javascript или любом другом языке в этом отношении)

function PartMetaData(dataElement){
this.metaData = new MetaData(dataElement);

this.get(name?) = function () {
    return this.metaData.getElement("data-part-" + name.toLower());
}

, так что вызывающий может все еще вызвать

partMetaData.getDescription();

Есть идеи?Я знаю, что могу изменить подпись и сделать ее одной функцией, я просто хочу знать, можно ли сохранить подпись как есть с помощью некоторой магии JS (черный?). Спасибо!

Ответы [ 2 ]

3 голосов
/ 01 марта 2012

Вы можете создать вспомогательную функцию, которую можно использовать для создания всех этих методов.

function PartMetaData(dataElement) {
    this.metaData = new MetaData(dataElement);

    function makeAccessor(o, itemName) {
        var ucase = itemName.substr(0,1).toUpperCase() + itemName.substr(1);
        o["get" + ucase] = function() {
            return this.metaData.getElement("data-part-" + itemName);
        }
    }

    var items = ["description", "weight", "height", "width", "length"];
    for (var i = 0; i < items.length; i++) {
        makeAccessor(this, items[i]);
    }
}

Более простой способ сделать это с немного другим интерфейсом был бы следующим:

function PartMetaData(dataElement) {
    this.metaData = new MetaData(dataElement);
    this.getProperty = function(name) {
        return this.metaData.getElement("data-part-" + name);
    }
}

И вы бы использовали это так:

partMetaData.getProperty("height");
0 голосов
/ 01 марта 2012

Да, расчесывание решений подруги прекрасно работает:

function PartMetaData(dataElement) {
    this.metaData = new MetaData(dataElement);

    this.getProperty = function(name) {
        return this.metaData.getElement("data-part-" + name);
    }

    this.makeAccessor = function(name) {
       this["get" + name.substr(0,1).toUpperCase() + name.substr(1)] =
          function() { return this.getProperty(name); }
    }

    var items = ["description", "weight", "height", "width", "length"];
    for (var i = 0; i < items.length; i++) {
        this.makeAccessor(this, items[i]);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...