2009-02-25 33 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!"