在我的Javascript中,我有一种工厂.根据传递的字符串,我将此字符串的新实例创建为对象.例如
function getEmployee (employeeType, department){
var fn = eval(employeeType);
return new fn(department);
}
Run Code Online (Sandbox Code Playgroud)
我不想在这里使用eval.我可以在employeeType上使用switch语句,但我不希望任何必须知道employeeType的依赖项.
还有另外一种方法可以做到吗?
为了扩展我原来的评论,每当我遇到这样的问题时,一般的解决方案是创建某种有效名称的全局注册表:
function Manager() { /* manager employee type */ }
function Intern() { /* intern employee type */ }
var registeredTypes = {
"manager": Manager,
"intern": Intern
};
Run Code Online (Sandbox Code Playgroud)
然后将您的函数编写为:
function getEmployee (employeeType, department) {
if (!(employeeType in registeredTypes))
throw "Invalid employee type: " + employeeType;
var fn = registeredTypes[employeeType];
return new fn(department);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您真的关心依赖关系,您甚至可以通过提供一种向注册表添加新员工类型的全局方法来进一步分离它:
function registerEmployeeType(employeeType, fn) {
if (employeeType in registeredTypes)
throw "Employee type already registered: " + employeeType;
if (typeof(fn) != "function")
throw "May only register employee types as functions: " + employeeType;
registeredTypes[employeeType] = fn;
}
Run Code Online (Sandbox Code Playgroud)
现在,你的核心功能,getEmployee并registerEmployeeType可以通过自己没有关于被注册的员工类型的任何信息声明.他们甚至可以从不同的脚本文件注册,只要它们运行后的registerEmployeeType定义.例如:
// core.js
var registeredTypes = { };
function getEmployee (employeeType, department) ...
function registerEmployeeType (employeeType, fn) ...
// manager.js
registerEmployeeType("manager", function() { /* manager employee type */ });
// intern.js
registerEmployeeType("intern", function() { /* intern employee type */ });
// index.html
<script src="core.js"></script>
<script src="manager.js"></script>
<script src="intern.js"></script>
Run Code Online (Sandbox Code Playgroud)