使用字符串 string 和 eval 以及多个函数和所有类型传递未知数量的变量
简而言之,我想使用对象文字来允许我以任意顺序将未知数量的变量传递给函数。虽然理论上这没什么大不了的,但在我的代码中,这个对象文字被传递给第二个名为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
实际上,您所拥有的是这样的:
...其中
foo
在该字符串上使用eval
,类似于:...并且您正在寻找如何嵌入 < code>params 其中。
您可以通过将对象文字序列化为字符串来实现此目的,这样当您将其与其他字符串组合并计算整个字符串时,它就会被计算。浏览器正在慢慢内置 JSON 序列化,但现在您想使用 jQuery、Prototype 或(如果您只想要这部分)来自 Crockford 的 json2.js,它提供了
JSON.stringify
,用于将可转换为 JSON 字符串的对象转换为 JSON 字符串。所以:但是您真正想要做的是重构,以便所有逻辑都表达为代码,而不是字符串中的代码。然后您可以直接传递文字,再加上一大堆其他好处,包括模块化、调试等
......更改
foo
以便它调用函数而不是eval
一个字符串。 (eval
应尽可能避免,用达赖喇嘛的话来说,它[几乎]总是可能的。)我的示例foo
更改为:If
foo< /code> 需要包含
bar
的附加信息(如果callBar
设置为处理这些额外参数),它可以使用Function#call
或Function#apply
来执行此操作。 (这些链接指向 MDC,但不用担心,它们不是 Firefox 特定的,它们已在 ECMA 规范中存在多年,并且几乎得到普遍支持。)In effect, what you have is this:
...where
foo
useseval
on that string, something like:...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: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.
...changing
foo
so that it calls a function rather thaneval
ing a string. (eval
is to be avoided whenever possible, and to paraphrase the Dalai Lama, it's [almost] always possible.) My samplefoo
changes to:If
foo
needs to include additional information forbar
(and ifcallBar
is set up to handle those extra arguments), it can useFunction#call
orFunction#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.)您不能将对象放入字符串中。您必须序列化该对象,将其添加到字符串中,然后将其解析回另一侧的结构化对象。最简单的方法是使用 JSON(通过
JSON.stringify
或针对没有它的旧浏览器的库回退),因为 JSON 计算为简单的 JavaScript。请注意,您不会得到完全相同的对象,而是一个具有相同属性和属性的新对象,并且它仅适用于简单类型,因此您不能在对象或任何内容中包含函数。
然而,无论如何,在字符串中传递 JavaScript 代码都是一种需要极力避免的反模式。相反,使用内联函数,您不必担心可以或不能放入字符串中的内容,并且可以摆脱所有不可读的包装和
\
-转义: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:一些可能对您有帮助的通用技术:
请参阅参数变量和call()。
Some general techniques which may be helpful for you:
See arguments variable and call().
为什么哦,为什么不创建一个包含参数和函数的对象,然后将其传递呢?接收函数可以在尝试使用对象之前测试对象的属性是否已设置。
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.