在Javascript中使用eval的替代方法

时间:2016-05-08 04:47:03

标签: javascript

在我的Javascript中,我有一种工厂。 根据传递的字符串,我将此字符串的新实例创建为对象。 例如

    function getEmployee (employeeType, department){
        var fn = eval(employeeType);
        return new fn(department);
    }

我不想在这里使用eval。 我可以在employeeType上使用switch语句,但我不希望任何必须知道employeeType的依赖项。

还有另外一种方法可以做到吗?

3 个答案:

答案 0 :(得分:5)

为了扩展我的原始评论,每当我遇到这样的问题时,一般的解决方案是创建某种有效名称的全局注册表:

function Manager() { /* manager employee type */ }
function Intern() { /* intern employee type */ }

var registeredTypes = {
    "manager": Manager,
    "intern": Intern
};

然后将您的函数编写为:

function getEmployee (employeeType, department) {
    if (!(employeeType in registeredTypes)) 
        throw "Invalid employee type: " + employeeType;
    var fn = registeredTypes[employeeType];
    return new fn(department);
}

但是,如果你真的关心依赖关系,你甚至可以通过提供一个向注册表添加新员工类型的全局方法来进一步分离它:

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;
}

现在,您的核心功能getEmployeeregisterEmployeeType可以自行声明,而无需任何有关正在注册的员工类型的信息。它们甚至可以从不同的脚本文件中注册,只要它们在定义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>

答案 1 :(得分:0)

您应该传递employeeType的函数而不是字符串(或更经典的 - 具有固定方法的对象),然后调用函数而不是eval

答案 2 :(得分:0)

感谢p.s.w.g我找到了答案。 我在工厂之前注册了这些类型。 我仍然将类型作为字符串传递给我的工厂,但是在注册类型中查找。

所以感谢你的评论。

function getEmployee (employeeType, department){
    var fn = registeredTypes[employeeType];
    return new fn(department);
}