-1

简而言之,我想使用对象文字来允许我以任意顺序将未知数量的变量传递给函数。虽然这在理论上没什么大不了的,但在我的代码中,这个对象字面量被传递给名为on_change.

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 加载一些内容,它工作正常并且会从on_change函数中触发代码。

我已经测试了这个load_xml功能,它能够调用alert(param.xpos)并得到正确的响应。我什至可以添加一个未定义的检查,这样我打电话的其余时间load_xml就不会被警报淹没。

load_xml函数首先设置on_change函数,然后调用该函数将内容加载到隐藏的 div。一旦 AJAX 请求更新了该 DIV,该on_change函数现在应该调用该parse_xml函数。这会从 xml 文件中提取信息。然而......这个对象文字参数的想法是它可以告诉这个parse_xml函数忽略某些事情。

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

这是 的一部分load_xml,即使有参数位,它也可以正常工作。除了,parse_xml似乎无法使用该参数。

我已经能够做到这一点,parse_xml可以alert(param)并给出[object object]我认为意味着对象文字已经通过的地步,但是当我尝试调用时,alert(param.xpos)我得到了未定义。

我知道这是一个问题,我可以通过让函数采用数不胜数的布尔参数来解决它,但这并不是一个很好的解决方案。

4

4 回答 4

2

实际上,您所拥有的是:

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

... where在该字符串上foo使用,例如:eval

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

...而您正在寻找如何嵌入params其中。

可以通过将对象文字序列化为字符串来做到这一点,这样当您将它与另一个字符串组合并评估整个字符串时,它就会被评估。浏览器正在慢慢内置 JSON 序列化,但现在你想使用 jQuery、Prototype 或(如果你只想要这部分)来自 Crockford 的 json2.js,它提供JSON.stringify了将可以转换为 JSON 字符串的对象转换为 JSON字符串。所以:

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

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

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

...改变foo,以便它调用一个函数而不是eval一个字符串。(eval应尽可能避免,用达赖喇嘛的话来说,这[几乎]总是可能的。)我的示例foo更改为:

function foo(func) {
    func();
}

如果foo需要包含额外的信息bar(并且如果callBar设置为处理这些额外的参数),它可以使用Function#callorFunction#apply来做到这一点。(这些链接指向 MDC,但不用担心,它们不是特定于 Firefox 的,它们已经在 ECMA 规范中多年并且几乎得到普遍支持。)

于 2010-03-24T12:45:56.777 回答
1

您不能将对象放在字符串中。您必须序列化对象,将其添加到字符串中,然后将其解析回另一端的结构化对象。最简单的方法是使用 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);
    }
});
于 2010-03-24T12:49:34.770 回答
0

一些可能对您有帮助的通用技术:

// 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, {});

请参阅参数变量和call()

于 2010-03-24T12:51:42.507 回答
0

我想使用对象文字来允许我以任意顺序将随机数量的变量传递给函数。

为什么哦,为什么不创建一个包含参数和函数的对象,然后传递呢?接收函数可以在尝试使用之前测试是否设置了对象的属性。

于 2010-03-24T12:54:04.620 回答