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

发布于 2024-08-26 00:52:40 字数 1724 浏览 9 评论 0原文

简而言之,我想使用对象文字来允许我以任意顺序将未知数量的变量传递给函数。虽然理论上这没什么大不了的,但在我的代码中,这个对象文字被传递给第二个名为 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) 时,我得到了未定义。

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

In short, I want to use an object literal to allow me to pass a unknown amount of variables in any order to a function. Whilst this is not big deal in theory, in my code, this object literal is passed to a second function called on_change.

on_change works by comparing an element's innerHTML to a string; If it is the same, it sets a timeout to call the function again. If the element's innerHTML is different from the string, then the third parameter is executed, this will either be a function or a string. either way it will execute. I have tested this function plenty and used it for a while now.

However, I cannot seem to get the object literal to flow through the function calls...

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 + ' ); }
');

I call this as part of the form submission. After this line, I then call a function to load some content via ajax, which works fine and will trigger the code from the on_change function.

I have tested the load_xml function, it is able to call alert(param.xpos) and get the correct response. I can even added in a check for being undefined so that rest of the times I call load_xml I don't get swamped with alerts.

The load_xml function first sets up the on_change function, then calls the function to load the content to a hidden div. Once the AJAX request has updated that DIV, the on_change function should now call the parse_xml function. This pulls out the information from the xml file. However... The idea of this object literal param is that it can tell this parse_xml function to ignore certain things.

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

This is part of load_xml, it works perfectly fine, even with the param bit in there. except, parse_xml does not seem to be able to use that parameter.

I have been able to get it to a point where parse_xml can alert(param) and give [object object] which I would of thought meant that the object literal had been passed through, but when I try and call alert(param.xpos) I get undefined.

I know this is a pig of a problem, and I could get around it by just having the function take a zillion boolean parameters, but its just not a very nice solution.

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

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

发布评论

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

评论(4

零度° 2024-09-02 00:52:40

实际上,您所拥有的是这样的:

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

...其中 foo 在该字符串上使用 eval ,类似于:

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

...并且您正在寻找如何嵌入 < code>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();
}

If foo< /code> 需要包含 bar 的附加信息(如果 callBar 设置为处理这些额外参数),它可以使用 Function#callFunction#apply 来执行此操作。 (这些链接指向 MDC,但不用担心,它们不是 Firefox 特定的,它们已在 ECMA 规范中存在多年,并且几乎得到普遍支持。)

In effect, what you have is this:

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

...where foo uses eval on that string, something like:

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

...and you're looking for how to embed params in that.

You could do this by serializing the object literal as a string so that when you combine it with the other string, and the total string is evaluated, it gets evaluated. Browsers are slowly getting JSON serialization built in, but for now you want to use jQuery, Prototype, or (if you just want this part) json2.js from Crockford, which offers JSON.stringify for turning objects that can be turned into JSON strings, into JSON strings. So:

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

But what you really want to do is refactor so that all of that logic is expressed as code, not code within a string. Then you could pass the literal directly, plus a whole raft of other benefits, including modularization, debugging, etc.

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

...changing foo so that it calls a function rather than evaling a string. (eval is to be avoided whenever possible, and to paraphrase the Dalai Lama, it's [almost] always possible.) My sample foo changes to:

function foo(func) {
    func();
}

If foo needs to include additional information for bar (and if callBar is set up to handle those extra arguments), it can use Function#call or Function#apply to do that. (Those links are to MDC, but don't worry, they're not Firefox-specific, they've been in the ECMA spec for years and are nearly universally supported.)

辞取 2024-09-02 00:52:40

您不能将对象放入字符串中。您必须序列化该对象,将其添加到字符串中,然后将其解析回另一侧的结构化对象。最简单的方法是使用 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);
    }
});

You can't put an object inside a string. You would have to serialise the object, add it into the string, then parse it back into a structured object on the other side. The simplest way to do that would be to use JSON (via JSON.stringify or a library fallback for older browsers that don't have it), since JSON evaluates as simple JavaScript.

Note that you wouldn't get the exact same object back, but a new one with the same attributes and properties, and it only works for simple types, so you can't include a function in the object or anything.

However, in any case, passing JavaScript code around in strings is an anti-pattern to be strenuously avoided. Instead use inline functions, and you don't have to worry about what you can and can't put in a string, and you can get rid of all that unreadable wrapping and \-escaping:

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);
    }
});
无畏 2024-09-02 00:52:40

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

// 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()

Some general techniques which may be helpful for you:

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

See arguments variable and call().

夜唯美灬不弃 2024-09-02 00:52:40

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

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

I want to use object literal to allow me to pass a random amount of variables in any order to a function.

Why oh why don't you just create an object which contains the parameters and functions, and pass that around? The receiving function can just test to see if a property of the object is set before trying to use it.

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