JS:在尝试将数组作为参数传递时在函数上使用 eval,但会引发错误

发布于 2024-10-04 02:33:31 字数 656 浏览 5 评论 0原文

我想使用 javascript 创建一个动态生成的表单,一切正常,直到我尝试传递一个数组作为参数。当我这样做时,会发生错误。谁能解释一下这是什么?

这是我的代码:

var loadFrm = function(component) {
    for(nItem in component) {
        var myComponent = "add" + firstToUpper(component[nItem].type);
    var callComponent = myComponent + "(" + component[nItem].opt + ");";
    eval(callComponent);
    }
}

var json = [
    {
        type: "scale",
        opt: {content: [{label: "male", value: "m"}, {label: "female", value: "f"}]}
    }
];

loadFrm(json);

编辑这是错误:

missing ] after element list
[Break on this error] addScale([object Object]);

i want to create a dynamic generated form using javascript, everything works fine, until i try to pass an array as parameter. When i do this, an error happens. Coulr anyone explain what this is?

Heres my code:

var loadFrm = function(component) {
    for(nItem in component) {
        var myComponent = "add" + firstToUpper(component[nItem].type);
    var callComponent = myComponent + "(" + component[nItem].opt + ");";
    eval(callComponent);
    }
}

var json = [
    {
        type: "scale",
        opt: {content: [{label: "male", value: "m"}, {label: "female", value: "f"}]}
    }
];

loadFrm(json);

Edit Here's the error:

missing ] after element list
[Break on this error] addScale([object Object]);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绝不服输 2024-10-11 02:33:31

如果您使用调试器查看字符串 callComponent,您可能会发现它看起来像这样:

addScale([object Object])

...这不是您想要的。这是因为您实际上是在 opt 对象上调用 toString,而对象上的默认 toString 看起来就像那样。 eval 错误是因为这是无效的语法。

一般来说,任何时候您认为需要使用eval,几乎肯定会有更好的答案。在本例中,您似乎正在尝试调用函数并传入 opt。假设这些函数是“全局函数”,您可以这样做:

var loadFrm = function(component) {
    var nItem, functionName;

    for (nItem = 0; nItem < component.length; ++nItem) {
        functionName = "add" + firstToUpper(component[nItem].type);
        window[functionName](component[nItem].opt);
    }
}

Live example

以上注释:

  1. 不要使用 for..in 循环遍历数组,除非您 真正知道自己在做什么for..in 不枚举数组的索引,它枚举对象的属性。
  2. 我们使用window[functionName]按名称查找函数。这是有效的,因为“全局变量”实际上是 window 对象的属性,并且您可以使用括号表示法使用字符串名称查找属性。
  3. 通过window[functionName]获得函数后,我们直接调用它,传入对象opt而不是它的字符串形式。我假设 addScale 期望看到一个对象。
  4. 我将所有 var 移至函数的顶部,因为那是它们真正所在的位置 (详细信息)。
  5. 如果可以的话,我建议将 addScale 和相关函数移动到它们自己的对象中,而不是将它们放在 window 上。 window 命名空间已经相当拥挤了。 这是一个实际示例,已修改为根本不向 window 添加任何符号,而是将 addScale 函数放在名为 functions 的对象上并从那里使用它。

离题:语法var loadFrm = function(component) 创建一个匿名函数,然后将其分配给一个变量。这被经常使用,但除非您根据条件创建不同的函数,例如:

var f;
if (...) {
    f = function() { ... };
}
else {
    f = function() { ... };
}

...它实际上没有用。 (如果您根据这样的条件创建不同的函数,那么它不仅有用,而且是必要的。)我建议尽可能使用命名函数,因为带有名称的函数可以帮助您的工具通过在错误消息、调用堆栈等中显示函数名称来帮助您。

离题 2:您有一个名为 json 的变量,但仅供参考,它没有使用 JSON 表示法。它使用 JavaScript 数组和对象文字表示法的组合,这是 JSON 的超集。你会看到很多人对此感到困惑,我提到它是因为你说你是新人,所以值得将其消灭在萌芽状态。 :-) JSON 纯粹是一种表示法。 (非常有用的一个。)

If you use a debugger to look at the string callComponent, you'll probably find it looks something like this:

addScale([object Object])

...which isn't what you want. That's because you're effectively calling toString on your opt object, and the default toString on objects just looks like that. The eval error is because that's invalid syntax.

Generally speaking, any time you think you need to use eval, there's almost certainly a better answer. In this case, it looks like you're trying to call a function and pass in opt. Assuming these functions are "globals", you can do that like this:

var loadFrm = function(component) {
    var nItem, functionName;

    for (nItem = 0; nItem < component.length; ++nItem) {
        functionName = "add" + firstToUpper(component[nItem].type);
        window[functionName](component[nItem].opt);
    }
}

Live example

Notes on the above:

  1. Don't use for..in to loop through arrays unless you really know what you're doing. for..in does not enumerate the indexes of an array, it enumerates the properties of an object.
  2. We look up the function by name using window[functionName]. This works because "globals" are actually properties of the window object, and you can look up properties using a string name for them using bracketed notation.
  3. Having gotten the function via window[functionName], we just call it directly, passing in the object opt rather than a string form of it. I assume addScale expects to see an object.
  4. I moved all of the vars to the top of the function because that's where they really are (details).
  5. If you can, I'd recommend moving addScale and the related functions to their own object rather than putting them on window. The window namespace is already pretty crowded. Here's the live example modified to not add any symbols to window at all, instead putting the addScale function on an object called functions and using it from there.

Off-topic: The syntax var loadFrm = function(component) creates an anonymous function that it then assigns to a variable. This is used a lot, but unless you're creating different functions based on a condition, e.g.:

var f;
if (...) {
    f = function() { ... };
}
else {
    f = function() { ... };
}

...it's not actually useful. (If you are creating different functions based on a condition like that, then it's not only useful, it's necessary.) I recommend using named functions whenever possible, because a function with a name helps your tools help you by showing you the function name in error messages, call stacks, etc.

Off-topic 2: You have a variable called json, but FYI, it's not using JSON notation. It's using a combination of JavaScript array and object literal notation, which is a superset of JSON. You'll see a lot of people confused about this, I mention it because you said you're new and so it's worth nipping in the bud. :-) JSON is purely a notation. (A very useful one.)

痴梦一场 2024-10-11 02:33:31

使用这个:

fn = eval(functionName);
fn(objParameter)

Use this:

fn = eval(functionName);
fn(objParameter)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文