覆盖javascript函数的return语句

时间:2011-12-02 20:03:57

标签: javascript metaprogramming

假设我有一个js函数。从程序中的其他一点来看,我想运行它的代码,但不是它的return语句。取而代之的是,我想运行一些其他的return语句来引用原始函数范围内的变量。

有没有办法做到这一点,除了加载函数源,替换返回,并在结果上使用eval?可以对原件进行最小的修改,但它不应该通过添加例如原件的性能来影响原件的性能。额外的函数调用。

5 个答案:

答案 0 :(得分:3)

你可以尝试这样的事情,但我不确定它是否符合你的条件。

编辑:已修复以在jsfiddle中工作

// Modified to set all "shared" variables as "members" of the function.
var test = function() {
    test.val = "one";
    test.val2 = "two";
    return 1;   
}

// Using different result
function test2() {
    test();
    return test.val2;
}

答案 1 :(得分:1)

您可以引入一个回调函数,如果可用则会被调用,否则将返回“标准”值。

function test(callback) {
  // ...
  return callback ? callback.call(this) : /* original value returned */ "xyz";
}

test(function() { /* "this" is same as in test() */ });

编辑:

如果你想在回调中传递变量,那么你只需在.call()函数中列出它们。

示例:

function test(callback) {
  var a = 4;
  var b = 2;
  // ...
  return callback ? callback.call(this, a, b) : a * b;
}

test(); // 8
test(function(a, b) { return a + b; }); // 6

请参阅this fiddle

答案 2 :(得分:1)

除非你能够重构你的方法以容纳callback或引入一些其他基于参数的逻辑流(不是第三方代码的选项),否则你运气不好。

这是一个回调示例(fiddle,归功于dzejkej's answer

function foo(callback) {
    var x = 2;   
    // pass your values into the callback
    return callback ? callback.call(this, x) : x * 2;
}
document.write(foo());
document.write("<hr/>");
// specify the parameters for your callback
document.write(foo(function(x){ return x * 4;}) );

答案 3 :(得分:0)

我认为你真的误解了 return statement 的概念。函数的return语句只返回一个值或一个对象,如果没有指定返回参数,则返回undefined。

如果你要做的只是执行一个函数但是“不是它的return语句”而不是你只是调用函数而不对返回的值/对象做任何事情:

但是,如果你的意思是你想要执行一个函数而不是对它的return语句执行“参数”,那么字面意思是选择性地执行函数体的任意部分。据我所知,这是不可能的(没有使用反射来获取函数定义,修改定义,然后动态调用修改后的版本 - 你说你不想这样做。)

答案 4 :(得分:0)

如果您将外部范围函数的变量保存在单个对象中,您可以尝试类似以下内容:

function original(a, b, c, rep) {
    var data = {};

    // Do some fancy stuff but make sure to keep everything under data
    data.a = a.replace(/foo/, 'bar');
    ...

    if ( Object.prototype.toString.call(rep) === '[object Function]' )
        return rep.call(data);

    return data;
}

function replacement() {
    return 'foo' + this.a;
}

// Now let's make use of both the original and the replacement ...
console.log(original('foo', x, y)); // => {a: "bar", b: ...}

console.log(original('foo', x, y, replacement)); // => {a: "foobar", b: ...}

希望,这就是你所要求的 欢呼声