【问题标题】:How do I create a new object in javascript based on a type-string?如何基于类型字符串在 javascript 中创建新对象?
【发布时间】:2011-05-20 15:04:36
【问题描述】:

如何在 javascript 中基于变量类型字符串(包含对象名称)创建新对象?

现在我有了:(随着更多工具的推出,列表将变得更长......)

function getTool(name){
  switch(name){
    case "SelectTool":
      return new SelectTool();
      break;
    case "LineTool":
      return new LineTool();
      break;
    case "BlurTool":
      return new BlurTool();
      break;
    case "PointerTool":
    default:
      return new PointerTool();
      break;
  }
}

并定义了我的工具,例如:

PointerTool.prototype = new Tool;
PointerTool.prototype.constructor = PointerTool;
function PointerTool(){
  this.name = "PointerTool";
}
PointerTool.prototype.click = function(x, y){
  info("You clicked at: "+x+", "+y);
}

我想使用(不断增长的)switch 语句,这似乎是“错误的”。

【问题讨论】:

  • 假设,eval 可以做到...
  • @Šime Vidas,但实际上,应该不惜一切代价避免 eval:D
  • @Gabi,我同意 eval() 在这里不是正确的解决方案,但我很好奇你为什么断言“应该不惜一切代价避免 eval”。它是该语言的一个不被弃用的特性,具有适当(和不适当)的用途——就像其他所有特性一样。
  • @Šime:我会请 Jeff 为 cmets 添加反对票! :-P
  • 有时eval 是唯一的答案,那就是应该使用它的时候。如果这些对象是在匿名自执行函数中定义的,则无法使用 window[constructor] 引用它们。

标签: javascript dynamic


【解决方案1】:
function getTool(name){
  return ( typeof window[name] === 'function' ) ? 
                                    new window[name]() : {/*some default*/};
}

假设PointerTool 构造函数定义在全局window 命名空间中。将其替换为您正在使用的任何命名空间。

【讨论】:

  • 如果你使用的是 Node.js,你可以使用 GLOBAL 对象来做同样的事情。
  • 我现在会使用这个解决方案,完全忘记了 everything 是一个函数,因此也是全局 window object/functions/namespace :)
  • @Dribbel - 听起来不错。我只使用了window,因为我不确定命名空间。如果您使用window,我建议在其他命名空间中定义它们。可以使用相同的技术,但如果 getTool 没有做任何其他事情,您可以消除该函数调用。
【解决方案2】:

您应该考虑重新考虑您的方法。最好有类似Tools 对象的东西,它将工具作为属性,如

Tools = {"SelectTool": SelectTool /* etc */}`.

这样,您可以以new Tools.SelectToolnew Tools[var_with_tool_name] 的身份访问这些工具。

【讨论】:

  • 是的,但即使工具位于不同的命名空间中也可以使用。
【解决方案3】:

在您的示例中,您将 PointerTool 声明为全局范围内的函数。假设您的 javascript 正在运行浏览器,“全局范围”实际上window 对象相同。这意味着如果你有一个构造函数:

function PointerTool() {
   ...
}

和这个是一样的:

window.PointerTool = function() {
   ...
}

所以现在,在你的 getTool 函数中,你可以像这样访问你的构造函数:

function getTool(name){
    return new window[name]();
}

更“面向未来”的方法是定义您自己的命名空间对象,您将在其中放置所有各种工具构造函数。像这样的东西(“myproject”将是您的项目或系统的简称):

var myproject = { tools: {} };

// Pointer Tool Constructor
myproject.tools.PointerTool = function() {
   ...
}

// Line Tool Constructor
myproject.tools.LineTool = function() {
   ...
}

// and so on

那么您的 getTool 函数将如下所示:

function getTool(name){
    return new myproject.tools[name]();
}

这种方法使您的内容与在全局/窗口范围内定义的任何其他内容隔离开来。

【讨论】:

  • 不,function PointerToolwindow.PointerTool = function:第一个是函数声明,第二个是函数表达式kangax.github.com/nfe/#expr-vs-decl
  • 没错,但在这个问题的上下文中,它已经足够了。也就是说,你可以使用window.PointerTool引用PointerTool,这就是这个答案的重点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 2015-06-20
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多