Javascript: лучший способ добавить динамические методы? - PullRequest
4 голосов
/ 25 февраля 2009

Мне интересно, есть ли лучший способ добавить динамические методы к существующему объекту. По сути, я пытаюсь динамически собрать новые методы, а затем добавить их в существующую функцию.

Этот демонстрационный код работает.

builder = function(fn, methods){

    //method builder
    for(p in methods){
        method = 'fn.' + p + '=' + methods[p];
        eval(method);
    }

    return fn;
}
test = {}
test = builder(test, {'one':'function(){ alert("one"); }','two':'function(){ alert("two"); }'} );

test.one();
test.two();

Ответы [ 5 ]

22 голосов
/ 25 февраля 2009

Вам не нужно каждый раз оценивать их.

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

var methods = {
  'increment': function() { this.value++; },
  'display' : function() { alert(this.value); }
};

function addMethods(object, methods) {
  for (var name in methods) {
    object[name] = methods[name];
  }
};

var obj = { value: 3 };
addMethods(obj, methods);
obj.display();  // "3"
obj.increment();
obj.display();  // "4"

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

function MyObj(value) {
  this.value = value;
};
MyObj.prototype.increment = function() {
  this.value++;
};
MyObj.prototype.display = function() {
  alert(this.value);
}
var obj = new MyObj(3);
obj.display();  // "3"
obj.increment();
obj.display();  // "4"
10 голосов
/ 02 апреля 2011

м-м-м - я могу немного опоздать, но в любом случае:

new Function(argName1,...,argNameN, body)

например:

x = new Function("y","return y*5");
x(3)

не намного лучше, чем eval. (Жаль, но в качестве описания кода используются строки, а не что-то более структурированное, как в LISP)

5 голосов
/ 21 августа 2014

Если вам нужен объект, динамически основанный на определенных типах ... Например:

var logTypes = ["fatal", "error", "warning", "info", "trace", "debug", "profile"];

Затем вы можете сохранить ссылку на вывод объекта "this" и использовать ее внутри методов.

function CustomLogger () {

   var outter = this;

   // creating the logger methods for all the log types and levels
   _.each(logTypes, function (logType) {
        outter[logType] = function (msg) {
           console.log("[%s] %s", logType, msg);
        };
   });
}

Таким образом, вы можете получить новые динамические методы ...

var logger = new CustomLogger();
logger.info("Super cool!");

Будет выведено следующее:

"[info] Super cool!"
1 голос
/ 25 февраля 2009

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

builder = function(fn, methods){

        //method builder
        for(p in methods){
                fn[p] = methods[p];
        }

        return fn;
}
test = {}
test = builder(test, {'one': function(){ alert("one"); },'two':function(){ alert("two"); }} );

test.one();
test.two();

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

0 голосов
/ 25 февраля 2009

Вам нужно строить методы из строки? Если нет, есть много способов, включая добавление методов в прототип объекта или определение объекта напрямую. В большинстве распространенных библиотек javascript есть методы для определения объектов / методов в существующих или создания «пространств имен». Проверьте YUI / Prototype / jQuery и т. Д. Для примеров того, как они реализуют.

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

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