2009-02-25 55 views
4

我想知道是否有更好的方法将动态方法添加到现有的对象。基本上,我试图动态组装新方法,然后将它们附加到现有函数。Javascript:更好的方法来添加动态方法?

此演示代码有效。

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(); 

回答

19

您不需要每次都评估它们。

您可以创建现有的函数对象,然后将它们作为属性分配给对象。

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" 
0

待办事项你必须从一个字符串构建方法?如果不是有很多方法,包括直接将方法添加到对象原型或对象定义。大多数常用的JavaScript库都有定义现有对象/方法或创建“命名空间”的方法。查看YUI/Prototype/jQuery等,了解它们如何实现。

否则,如果您必须从字符串构建,那么评估可能是将方法动态添加到对象定义的最佳方法。

1

你的例子可以不附带任何条件来完成:

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(); 

我不知道你是如何组装这些方法,但如果你能避免使用字符串。可能有更好的方法。

8

mhmh - 我可能有点晚了,但无论如何:

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

例如:

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

比EVAL更好,虽然。 (这是一个遗憾,但字符串作为代码的描述,不是更有条理在LISP)

3

如果你需要一个对象动态地根据特定类型的...例如:

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!"