Search code examples
javascriptclassoopobjectcall

Change the "this" only for a specific function call


Let's say I have this code (that's an example, simplified):

// A Thing that expands other thing can use it's origin Thing's "init".
ThingThatExpands.super = function() {
    this.__originThing.init.apply(this, arguments);
}

// I make a Car Thing and give a color and a speed.
var Car = Thing("Toy Car", {
    init: function(color, speed) {
        this.color = color;
        this.speed = speed;
    }
});

// Then I make a Racing Car, which inherits the color and speed properties from it's origin
// (that's "Car", of course), but also has a cool sound!
var RacingCar = ThingThatExpands(Car, "Toy Police Car", {
    init: function() {
        this.super("#00F", 180);
        this.sound = "Wee-ooh! Wee-ooh!"
    }
})

Now, since "RacingCar" is a "child" of "Car", it has it's attributes and a nice "super" function that can be used to call "Car's" init.

Alright. The problem is: Since the "super" function gives the "child" Thing as the "this", it will change the "child" attributes, right? Ok, that's what we need. But... It also means the "super" will be called from the "child" not the "origin" Thing, which shouldn't happen (and won't work).

Can I somehow "protect" the "this.super" call?


Solution

  • To change the scope for a specific function, you must bind that function to the object of the desired scope.

    So if you want foo.bar() to be called, but from the scope of baz, use foo.bar.call(baz) if you want the function to run right then, or use foo.bar.bind(baz) if you want it to use that scope when it is called in the app at run-time.