我有一个接受字符串对象名称的函数,我需要该函数创建一个与字符串值同名的对象的新实例
例如,
function Foo(){}
function create(name){
return new name();
}
create('Foo'); //should be equivalent to new Foo();
虽然我知道这可以通过 eval 实现,但最好尽量避免使用它。如果有人对这个问题有其他想法(如下),我也很感兴趣
我有一个数据库和一组(使用经典的 OO 方法)类,每个表大致对应一个类,定义该表上的常见操作。 (对于那些使用 PHP 的人来说非常类似于 Zend_Db)。由于一切都是异步的,因此根据最后一个结果执行任务可能会导致代码缩进很多
var table1 = new Table1Db();
table1.doFoo({
success:function(){
var table2 = new Table2Db();
table2.doBar({
notFound:function(){
doStuff();
}
});
}
});
显而易见的解决方案是创建抽象代码的异步性质的辅助方法。
Db.using(db) //the database object
.require('Table1', 'doFoo', 'success') //table name, function, excpected callback
.require('Table2', 'doBar', 'notFound')
.then(doStuff);
这简化了事情。然而,问题是我需要能够创建表类,其名称可以从传递给 require
的第一个扩充中推断出来,这导致我遇到了上面的问题......
最佳答案
为什么不直接将构造函数传递给require
方法呢?这样你就回避了从名称到函数的整个转换问题。您的示例将如下所示:
Db.using(db) //the database object
.require(Table1Db, 'doFoo', 'success') //table constructor, function name, expected callback
.require(Table2Db, 'doBar', 'notFound')
.then(doStuff);
但是,如果你真的想使用字符串...
为什么您坚决避免使用 eval
?它是语言中的一种工具,每个工具都有其用途(就像每个工具都可能被滥用一样)。如果您担心允许任意执行,一个简单的正则表达式测试应该使您的使用安全。
如果您坚决避免 eval
并且如果您的所有构造函数都是在默认全局范围(即 window 对象)中创建的,那么这将起作用:
function create(name) {
return new window[name]();
}
如果你想要花哨并支持命名空间对象(即 create('MyCompany.MyLibrary.MyObject')
,你可以这样做:
function create(name) {
var current,
parts,
constructorName;
parts = name.split('.');
constructorName = parts[parts.length - 1];
current = window;
for (var i = 0; i < parts.length - 1; i++) {
current = current[parts[i]];
}
return new current[constructorName]();
}
关于javascript - 动态对象创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3216892/