代码之家  ›  专栏  ›  技术社区  ›  thecoshman

通过字符串和eval以及多个函数和所有类型传递未知量的变量

  •  -1
  • thecoshman  · 技术社区  · 14 年前

    简言之,我想使用一个对象文字来允许我以任何顺序向函数传递未知数量的变量。虽然这在理论上并不重要,但在我的代码中,这个对象文本被传递给第二个名为 on_change .

    零钱 工作方式是将元素的innerHTML与字符串进行比较;如果相同,则设置再次调用函数的超时。如果元素的innerHTML与字符串不同,则执行第三个参数,这将是函数或字符串。不管是哪种方式。我已经对这个函数进行了大量的测试,并使用了一段时间。

    然而,我似乎无法让对象文字通过函数调用…

    var params = { xpos:'false'};
    on_change('window_3_cont_buffer','','
    if(Window_manager.windows[3].window_cont_buffer.getElementsByTagName(\'content\')[0].getElementsByTagName(\'p\')[0].innerHTML == \'ERROR\'){
    alert(Window_manager.windows[3].window_cont_buffer.getElementsByTagName(\'content\')[0].getElementsByTagName(\'p\')[1].innerHTML);
    return false;
    } else { 
    Window_manager.windows[3].load_xml(\'location/view.php?location_ID=3\', \'\', ' + params + ' ); }
    ');
    

    我称之为表格提交的一部分。在这一行之后,我调用一个函数通过ajax加载一些内容,这个函数运行良好,并将从 零钱 功能。

    我已经测试了 load_xml 函数,它可以调用 alert(param.xpos) 得到正确的回答。我甚至可以加上一张未定义的支票,这样我以后打电话 加载XML 我不会被警报淹没。

    这个 加载XML 函数首先设置 零钱 函数,然后调用函数将内容加载到隐藏的div中。 零钱 函数现在应该调用 parse_xml 功能。这将从xml文件中提取信息。然而。。。这个对象literal param的思想是它可以告诉 PARSEXML 忽略某些事物的功能。

    on_change("window_" + this.id + "_cont_buffer", "", "Window_manager.windows[" + this.id + "].parse_xml('" + param + "')");
    

    这是 加载XML ,它工作得非常好,即使里面有param位。除了, PARSEXML 似乎无法使用该参数。

    我已经把它弄到了 PARSEXML 可以 alert(param) 给予 [object object] 我本以为这意味着对象文字已经被传递了,但是当我试图调用 警报(参数xpos) 我没有定义。

    我知道这是一个棘手的问题,我可以让函数接受无数布尔参数来解决它,但这不是一个很好的解决方案。

    4 回复  |  直到 10 年前
        1
  •  2
  •   T.J. Crowder    14 年前

    实际上,你得到的是:

    var params = {param: "value"};
    foo("bar('one', 'two', 'three');");
    

    …在哪里 foo 使用 eval 在那根绳子上,像是:

    function foo(codestring) {
        eval(codestring);
    }
    

    …你在寻找如何嵌入 params 在那。

    能够 通过将对象文本序列化为字符串来执行此操作,以便在将其与另一个字符串组合时,计算出整个字符串的值。浏览器正在慢慢地获得内置的json序列化,但是现在您想要使用jquery、prototype或(如果您只是想要这个部分的话) json2.js from Crockford ,它提供 JSON.stringify 用于将可以转换为json字符串的对象转换为json字符串。所以:

    var params = {param: "value"};
    foo("bar(" + JSON.stringify(params) + ");");
    

    但你是什么 真正地 要做的是重构,以便所有的逻辑都表示为代码,而不是字符串中的代码。然后您可以直接传递文本,再加上一系列其他好处,包括模块化、调试等。

    var params = {param: "value"};
    function callBar() {
       bar(params);
    }
    foo(callBar);
    

    ……变化 所以它调用一个函数而不是 埃瓦 一根绳子。( 埃瓦 在任何可能的情况下都要避免,套用达赖喇嘛的话,这几乎总是可能的。 更改为:

    function foo(func) {
        func();
    }
    

    如果 需要包括 bar (如果) callBar 它可以使用 Function#call Function#apply 这样做。(这些链接是指向mdc的,但不用担心,它们不是firefox特有的,它们在ecma规范中已经存在多年,而且几乎得到了普遍支持。)

        2
  •  1
  •   bobince    14 年前

    不能将对象放在字符串中。您必须序列化对象,将其添加到字符串中,然后将其解析回另一侧的结构化对象中。最简单的方法是使用json(通过 JSON.stringify 或者是一个库回退,用于没有它的旧浏览器),因为json的计算结果是简单的javascript。

    请注意,您不会得到完全相同的对象,而是一个具有相同属性和属性的新对象,而且它只适用于简单类型,因此不能在对象或任何内容中包含函数。

    然而,无论如何,要极力避免在字符串中传递javascript代码是一种反模式。相反,使用内联函数,你不必担心你能不能放入一个字符串,你可以去掉所有不可读的包装和 \ -逃逸:

    var params = {xpos: 'false'};
    on_change('window_3_cont_buffer', '', function() {
        var w= Window_manager.windows[3];
        var ps= w.window_cont_buffer.getElementsByTagName('content')[0].getElementsByTagName('p');
        if (ps[0].innerHTML==='ERROR') {
            alert(ps[1].innerHTML);
            return false;
        } else { 
            w.load_xml('location/view.php?location_ID=3', '', params);
        }
    });
    
        3
  •  0
  •   jholster    14 年前

    一些可能对您有帮助的一般技巧:

    // Example of calling function objects given as arguments:
    
    function on_change(foo, callback1, callback2) {
        if (foo)
            callback1();
        else
            callback2.call(available_as_this);
    }
    
    on_change(foo, function() { your code }, function() { another code });
    
    
    // Example of function taking arbitrary number of arguments:
    
    function any_params() {
        console.log('I got ' + arguments.length + 'arguments!');
        console.log('First argument: ' + arguments[0]);
    }
    
    any_params('one', 'two', 'three', [], null, {});
    

    arguments 变量和 call() .

        4
  •  0
  •   BenMorel Manish Pradhan    11 年前

    我想使用object literal来允许以任意顺序向函数传递随机数量的变量。

    为什么不创建一个包含参数和函数的对象,然后把它传递出去呢?接收函数可以只测试对象的属性是否已设置,然后再尝试使用它。