1

I have a function that looks like this:

function outer() {
    function inner_1() {
        alert('inner_1');
    }

    function inner_2() {
        alert('inner_2');
    }

    function inner_3() {
        alert('inner_3');
    }

    inner_1();
    inner_2();
    inner_3();
}

I need to call outer(), but I want to replace inner_1() with another function.

I have tried this:

new_outer = outer;

new_outer.inner_1 = function() {
    alert('my new inner function');
};

If I try to call the newly redefined inner_1 like this:

new_outer.inner_1();

it works as expected ('my new inner function' is alerted).

But if I try to call the outer function:

new_outer();

the old version of inner_1 is called.

I want to redefine inner_1 and the call outer. How can I achieve this?

infrared
  • 3,566
  • 2
  • 25
  • 37
  • The only way to do that in JavaScript (and I absolutely don't recommend writing code like this) would be to call `.toString()` on the outer function, replace the inner function, and then convert back to an actual function. Once a function is instantiated, it cannot be changed (and note that the horrific process described above would not change the function, but instead create a new one). – Pointy Mar 04 '13 at 18:50
  • 2
    It can't be done without changing `outer`. Can you receive an argument, such as a flag telling which `inner1` should be used, or perhaps receive `inner1` as an argument? – John Dvorak Mar 04 '13 at 18:50
  • 1
    @Pointy it won't work if `outer` closes over something not visible from the caller – John Dvorak Mar 04 '13 at 18:51
  • 4
    I smell an XY problem here, maybe? http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – ultranaut Mar 04 '13 at 18:53
  • Can you change the way the functions are declared in `outer` to use function expressions? Like `var inner1 = function()...` – mike Mar 04 '13 at 18:54
  • What is the underlying goal you are trying to accomplish? What you are suggesting violates the open/closed principle. There is probably a better way to achieve your goal. – Aaron Kurtzhals Mar 04 '13 at 18:54
  • @mike won't help much – John Dvorak Mar 04 '13 at 18:54
  • @mike: How would that help? – gen_Eric Mar 04 '13 at 18:55
  • Can you pass in an argument that contains the function you want to call, and then invoke it something like: http://stackoverflow.com/questions/1723287/calling-a-javascript-function-named-in-a-variable ? – jeconner Mar 04 '13 at 18:55
  • The best way is to pass `inner_1` as a parameter to `outer`. If a value was passed use it, otherwise use the "default". – gen_Eric Mar 04 '13 at 18:56
  • @jeconner: Or pass the function itself as a parameter, and not its name. – gen_Eric Mar 04 '13 at 18:57
  • @JanDvorak yes that's certainly true - I wish it wouldn't **ever** work because it's clearly insane. – Pointy Mar 04 '13 at 19:01
  • 2
    @Pointy: I hope no one actually tries to do it that way :O – gen_Eric Mar 04 '13 at 19:03
  • 1
    @RocketHazmat maybe as a learning experi... no. – John Dvorak Mar 04 '13 at 19:04
  • 1
    I feel bad about suggesting it but I feared making a blanket "it's impossible" statement because TJ Crowder's been logged in today :-) – Pointy Mar 04 '13 at 19:07

1 Answers1

0

This seems like a really bad idea so I am not going to post any code. However, if you are pursuing the answer for "educational purposes only", I will just hint that although you cannot easily redefine a function from outside its scope (as per your example), there is nothing stopping you from redefining a function attached to a function object.

I do think, however, there is a better solution to whatever the problem you are trying to solve is.

igoratron
  • 134
  • 3