我想知道是否有更好的方法将动态方法添加到现有对象。基本上,我试图动态组装新方法,然后将它们附加到现有函数。
此演示代码有效。
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();
答案 0 :(得分:22)
每次都不需要评估它们。
您可以创建现有的功能对象,然后将它们作为属性分配给对象。
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"
答案 1 :(得分:10)
new Function(argName1,...,argNameN, body)
例如:
x = new Function("y","return y*5");
x(3)
但是,并不比eval更好。 (很遗憾,但是字符串被用作代码描述,而不是像LISP那样更有条理的东西)
答案 2 :(得分:5)
如果根据特定类型动态需要对象...例如:
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!"
答案 3 :(得分: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();
我不确定你是如何组装这些方法的,但如果可以,请避免使用字符串。可能有更好的方法。
答案 4 :(得分:0)
您是否必须从字符串构建方法?如果没有,有很多方法包括直接将方法添加到对象原型或对象定义。大多数常见的javascript库都有定义现有对象/方法或创建“命名空间”的方法。查看YUI / Prototype / jQuery等,了解它们如何实现的示例。
否则,如果必须从字符串构建,则evaling可能是将方法动态添加到对象定义的最佳方法。