0

I need to edit the function which locates inside of the constructor. Example:

some.thing = function() {
    this.somefn = function() { // this is the function that I need to fix
        ...
    }
}

But function should be edited not just only for a single object (new obj = some.thing();) but also for any created objects by this constructor.

So is there any way to edit such inner-functions?

6
  • 1
    Why is the function inside the constructor, and not on the .prototype of the constructor? Does it need variable access in the constructor? Commented Oct 10, 2012 at 18:51
  • 1
    No... all you can do is overwrite obj.somefn for each newly created instance. Commented Oct 10, 2012 at 18:52
  • @FelixKling unless OP controls the declaration and can make it a property of the prototype... Commented Oct 10, 2012 at 18:54
  • user1689607, I can't to access this function using .prototype... Commented Oct 10, 2012 at 18:54
  • @NikitaGavrilov because it's not a member of the prototype. If it were, you'd be all set. Commented Oct 10, 2012 at 18:55

3 Answers 3

2

Here is a solution based on prototype:

var Something = function () {
    this.f = function () {
       console.log("Something");
    };    
};
var Old = Something;
var Something = function () {
    Old.apply(this);
    this.f = function () {
        console.log("New");
    };
};
Something.prototype = new Old();

var s = new Something();
s.f(); // prints "New"
Sign up to request clarification or add additional context in comments.

1 Comment

Nice. Check out these adjustments, you can keep Old from polluting and avoid calling it with new: jsfiddle.net/V6zve
2

The solutions seem just a little too obvious, so I'm wondering if the trouble is that you don't have access to the original code, and you need a more dynamic solution.

If so, one option may be to override the constructor with your own constructor, and have it call the original, and then update the object.


Original code:

some.thing = function() {
    this.somefn = function() { // this is the function that I need to fix
        ...
    }
}

Your code:

       // cache a reference to the original constructor
var _thing = some.thing;

               // your constructor
some.thing = function() {

             // invoke the original constructor on the new object.
    _thing.apply(this, arguments);

    this.somefn = function() { /*your updated function*/ };
};

        // maintain inheritance
some.thing.prototype = Object.create(some.thing.prototype);

  // make an instance
var theThing = new some.thing();

Now you're getting the benefit of the original constructor and prototype chain, but you're injecting your own function on to the objects being created.

Only trouble may be that the original function you replaced could make special use of the original constructor's variable scope. If that's the case, there would be an issue to resolve.

It would be possible to retain and invoke the original method that you overwrote before invoking yours. Not sure if this situation calls for that or not.

4 Comments

Unfortunately it does not works, I got an error in Chrome RangeError: Maximum call stack size exceeded and the function still the same
@NikitaGavrilov: Then you did something differently. Here's a demo. jsfiddle.net/xzW9Z Make sure that your new constructor calls the original, and not itself.
Could it be that I've got an error because of the heavy constructor?
@NikitaGavrilov: Not really. This answer is effectively the same as the other one. (It is now anyway, since that one added Old.apply(this); to invoke the original constructor like mine does.) I did have a mistake in the code at first, but I corrected it about 2 minutes after I posted the answer.
0

I exactly know your need cause last week I passed through it. I just implemented a complete inheritance model in javascript and as far as I remember, I had a problem with overriding constructors and calling the parent class's ctor when child class is initializing.

So I just solved the problem with modifing some points in my design and it's now working like a charm! (something like C# but in Javascript)

By the way, I don't suggest you to change a method contents this way, but here is a way to do that (I myself did not do that this way and AGIAIN I DO NOT RECOMMEND IT. THERE ARE MANY OTHER WAYS, BUT THIS IS THE EASIEST):

var test = function() { /*InjectionPlace*/ };

eval("var newTest = " + test.toString().replace(
     "/*InjectionPlace*/", 
     "var i = 10; alert(i);"
));

test();

newTest();

Cheers

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.