Alexandros Marinos
Alexandros Marinos

Reputation: 1396

overriding a javascript function's return statement

Assume I have a js function. From some other point in the program, I want to run its code, but not its return statement. In its place, I would like to run some other return statement that references the variables in the scope of the original function.

Is there a way to do this, other than loading up the function source, replacing the return, and using eval on the result? Minimal modification of the original is possible, though it should not affect the original's performance by adding e.g. an extra function call.

Upvotes: 2

Views: 638

Answers (5)

John Fisher
John Fisher

Reputation: 22717

You could try something like this, but I'm not sure it meets your conditions.

Edit: Fixed to work in 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;
}

Upvotes: 3

kubetz
kubetz

Reputation: 8566

You can introduce a callback function that will get called if available otherwise "standard" value will be returned.

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

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

EDIT:

If you want to pass variables inside callback then you just list them in the .call() function.

Example:

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

See this fiddle.

Upvotes: 1

canon
canon

Reputation: 41695

Unless you're able to restructure your methods to accommodate a callback or introduce some other parameter-based logic-flow (not an option for 3rd party code), you're out of luck.

Here's a callback sample (fiddle, credit to 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;}) );

Upvotes: 1

Mike Dinescu
Mike Dinescu

Reputation: 55750

I think you really misunderstand the concept of return statement. The return statement of a function will simply return a value, or an object, or undefined if there is no return parameter specified.

If all you're trying to do is execute a function but "not its return statement" than you would just invoke the function and not do anything with the returned value/object:

However, if what you mean is that you would like to execute a function but not execute the "parameter" to its return statement then that literally means to selectively execute an arbitrary portion of the body of a function. And as far as I know that is not possible (without using reflection to get the function definition, modify the definition, and then dynamically invoking the modified version - which you said you didn't want to do).

Upvotes: 0

aefxx
aefxx

Reputation: 25279

Provided that you would keep variables of the outer scope function within a single object, you could try something like the following:

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: ...}

Hope, it's what you where asking for.
cheers

Upvotes: 0

Related Questions