Чтобы расширить мой оригинальный комментарий, всякий раз, когда я столкнулся с проблемой, как это, общее решение заключается в создании какой-то глобальный реестр действительных имен:
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;
}
Теперь ваши основные функции, 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>
Можете ли вы создать глобальный реестр типов сотрудников, например. 'var employeeTypes = {" manager ": Менеджер," intern ": Intern}'? или вы считаете это как зависимость? –
'fn = window [employeeType]' является альтернативой, если вы заранее не знаете типы, но решение @p.s.w.g безопаснее. В любом случае, нет необходимости в 'evil()'. – Amadan
Могли бы вы не просто иметь employeeType, являющийся объектом с разными прототипами для фабрики? – Soren