Peregring-lk Peregring-lk - 25 days ago 8
Javascript Question

Clone javascript function

I have a function constructor which creates an object with a function, say,

do_it
:

function do_it_maker() {
this.do_it = function() { /* do something */ };
this.other_do = function() { /* do anything else */ };
}


And I want to create a wrapper for a
do_it_maker
object enriching the
do_it
behaviour through parasitic inheritance:

function do_it_maker_wrapper() {
var do_it_obj = new do_it_maker();

do_it_obj.do_it_original = do_it_obj.do_it;

do_it_obj.do_it = function() {
do_it_obj.do_it_original();
/* smth_else */
}

return do_it_obj;
}

var do_it_obj = new do_it_maker_wrapper();
do_it_obj.do_it(); // Reimplemented version.
do_it_obj.other_do(); // Untouched.


My question is, will the
do_it_obj.do_it()
call cause a recursive call? or the reference to the original
do_it
function is still alive?

I have found related questions here in StackOverflow but I have read contradictory answer about if the method must be cloned or not.

So, what will it happen? In case the reference becomes recursive after changing
do_it
, which is the most understandable and with the fewest amount of code required way of cloning that method? I'm a C++ and not-happy-with-just-copy-paste-code guy and some Javascript features look still obscure to me (I'm not clumpsy though, you can do it a bit hard).

Answer

it will call the original function, no recursion will occur

function do_it_maker_wrapper() {
    var do_it_obj = new do_it_maker();

    // in this line you save/keep the reference to 'do_it' original function on a 
    // completely new reference.
    do_it_obj.do_it_original = do_it_obj.do_it;

    // this line replaces the reference to original 'do_it' with a reference to a
    // new function that we create here
    do_it_obj.do_it = function() {

         // this still references the original 'do_it' function so that is called
         do_it_obj.do_it_original();
         / * smth_else */
    }
}.

var do_it_obj = new do_it_maker_wrapper();

// this property references the function that we created as a replacement for the original 'do_it'
do_it_obj.do_it();

EDIT: with ES6 being available pretty much everywhere now you do not need to jump the hoops like that anymore and just use 'class' and 'extend' like you would in any other OO language. It actually even helps runtimes like v8 to optimize your code better and it is as fast as creating a simple hash with curly brackets '{}'