【发布时间】:2012-03-02 14:11:25
【问题描述】:
在 PHP 中,字符串可用于动态选择类进行实例化。以下是 PHP 中的 2 个简单类:
<?php
class Magic implements Genius {
public function perform() {
echo 'madya look :P' . PHP_EOL;
}
}
class Genie implements Genius {
public function perform() {
echo 'your wish has been granted!' . PHP_EOL;
}
}
现在可能有一个变量,使得在运行时实例化的类基于其内容
$sGeniusClass = 'Magic';
$oGenius = new $sGeniusClass();
现在在 Javascript 中,我喜欢使用函数作为构造函数来获得某种程度的类型化,在这种情况下,我可能会有:
function Magic() {}
Magic.prototype = {
perform : function()
{
console.log('madya look :P');
}
}
function Genie() {}
Genie.prototype = {
perform : function()
{
console.log('your wish has been granted!');
}
}
我知道我可以使用 eval 来完成类似于 PHP 的操作:
方法#1
var sClassName = 'Genie';
eval('var oGenius = new ' + sClassName);
我还看到 an approach 调用 Function 函数:
方法 #2
var sClassName = 'Genie';
var oGenius = new Function('return new ' + sClassName)();
On the MDN 虽然听起来这会在每次创建实例时重新评估性能:
使用 Function 构造函数创建的函数对象在以下情况下被解析 函数被创建。这比声明一个效率低 函数并在您的代码中调用它,因为函数声明 带有函数的语句与其余代码一起解析。
现在我还有一种方法有点乏味:
方法#3
var aClassMap = {
Magic : Magic,
Genie : Genie,
create : function(sClassName) {
if(this[sClassName] === undefined)
return false;
return new this[sClassName];
}
}
var sClassName = 'Genie';
var oGenius = aClassMap.create(sClassName);
这似乎是我最喜欢的整体,没有使用 eval,也没有后续的重新评估,如解决方案 #2。不过,这仍然需要一些工作,所以我的问题是双重的:
- 除了我展示的 3 种方法之外,还有其他方法可以做到这一点吗?
- 是否有类似于 PHP 的东西,其中字符串可以映射到要实例化的函数?
【问题讨论】:
-
如何使用方法#2 将参数传递给新函数?所以它会像这样执行:
new Genie('foo')foo也是一个变量? -
找到了!它是这样的:
var oGenius = new Function('arg1', 'return new ' + sClassName + '(arg1)')($argumentVariable);
标签: php javascript oop function dynamic