2

我从 jquery 的 json 调用中接收到一些“正文”内容,我可以在其中获取通过执行以下操作返回的唯一 javascript 元素:

script_element = $(data.body)[1]

这等于:

<script type=​"text/​javascript">​
    updater('foo', 'bar', {}, '0', constant='');
</script>​

所以,typeof script_element返回"object"

而且,如果我运行script_element.innerText,我可以获得:

updater('foo', 'bar', {}, '0', constant='');

收到这个脚本后,我现在正在做的只是eval在上面运行一个,但是四处搜索我找不到运行eval更改函数调用参数的方法。

我想要做的是改变third调用的参数,在这种情况下{},它可以根据 json 调用的返回而改变,所以我不能只搜索{}.

例如,我也可以这样做script_element.text.split(',')[2],并即时更改此文本,但我认为应该有更好的方法来做到这一点。

我不知道javascript是否可以识别和处理“未来的方法调用”,但仍然认为应该有更好的方法。

任何的想法?

4

4 回答 4

5

您可以做的是隐藏函数以便能够更改第三个参数。您应该在获取 JSON 之前定义该阴影函数。

var originalUpdater = updater; // keep old function to call

// overwrite (shadowing)
updater = function(a, b, c, d, e) {
    // change c appropriately here
    originalUpdater(a, b, c, d, e);
}

然后你仍然可以eval使用它(这不是很安全,但如果我没记错的话,这不是你的意思),它会调用影子函数。


一种更通用的阴影方法将遵循以下原则:

var originalUpdater = updater; // keep old function to call

// overwrite (shadowing)
updater = function() {
    // change arguments[2] appropriately here
    originalUpdater.apply(this, arguments);
}

小提琴:http: //jsfiddle.net/n7dLX/

于 2011-07-18T17:08:22.333 回答
3

更换服务器。而不是返回

<script type=​"text/​javascript">​
    updater('foo', 'bar', {}, '0', constant='');
</script>​

返回

{
  "method": "updater",
  "params": [
    "foo", "bar", {}, "0", ''
  ]
}
于 2011-07-18T17:11:40.163 回答
2

假设您无法更改从服务器发送的内容,您可以简单地innerText使用正则表达式运行并在插入之前传递更新 HTML。

var replacer = /\w+\(([^()]+)\)/gi;
script_element.innerText.replace(replacer, function(matched_text, func_params){
    var orig_func_params = func_params;
    // Make changes to func_params here.
    return matched_text.replace(orig_func_params, func_params);
});

这可以通过执行以下操作来实现:

var replacer = /\w+\(([^()]+)\)/gi;
function replace_arg(script_element, arg_index, replacement_value) {
    script_element.innerHTML = script_element.innerHTML.replace(replacer, 
    function(matched_text, func_params){
        var orig_func_params = func_params;
        func_params = func_params.split(",");
        if (arg_index >= func_params.length) {
             throw new RangeError(arg_index + " is out of range. Total args in function:" + func_params.length);
        }
        func_params[arg_index] = JSON.stringify(replacement_value);
        return matched_text.replace(orig_func_params, func_params.join(","));
    });
return script_element;
}

可以这样调用:

script_element = replace_arg(script_element, 3, {"new":"arg"});
于 2011-07-18T17:11:43.063 回答
0

我不明白您在做什么,但一般来说,如果您不想依赖参数的顺序,请让函数采用一个参数,该参数是一个对象,其属性是参数:

function add(params) {
    var a = params.hasOwnProperty("paramA") ? params.paramA : 0;
    var b = params.hasOwnProperty("paramB") ? params.paramB : 0;
    return a + b;
}

add({paramA: 1, paramB: 2});

在这种情况下,您应该在尝试访问之前使用 hasOwnProperty 检查函数是否传递了您要查找的参数。

于 2011-07-18T17:11:23.657 回答