Javascript: better way to add dynamic methods?
Solution 1
You don't need to eval them each time.
You can create existing function objects, then assign them as properties to your objects.
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"
The canonical, object-oriented way however, is to use constructors and prototypes, but this isn't really dynamic in that each object you construct will have the same methods:
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"
Solution 2
mhmh - I may be a bit late, but anyway:
new Function(argName1,...,argNameN, body)
for example:
x = new Function("y","return y*5");
x(3)
not much better than eval, though. (it's a pity, but strings are used as code-description, not something more structured as in LISP)
Solution 3
If you need an object dynamically based on specific types... For instance:
var logTypes = ["fatal", "error", "warning", "info", "trace", "debug", "profile"];
Then you can keep a reference of the "this" object output and use it inside the methods.
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);
};
});
}
That way, you can get the new dynamic methods...
var logger = new CustomLogger();
logger.info("Super cool!");
This will output the following:
"[info] Super cool!"
Solution 4
Your example could be accomplished without strings:
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();
I'm not sure how you are assembling these methods, but avoid using strings if you can. There is probably a better way.
Geuis
Updated on August 21, 2020Comments
-
Geuis almost 4 years
I'm wondering if there's a better way to add dynamic methods to an existing object. Basically, I am trying to assemble new methods dynamically and then append them to an existing function.
This demo code works.
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();