0

I'm no doubt doing something dumb here, but the following code results in an

error "this.getString is not a function." 

This occurs because when unrelatedInstance calls stringGetter, "this" in showCombinedStrings() has the value of Unrelated....which actually seems fair enough, but how could this be set up so that it would work?

function BaseStringGetter() {
    this.getString = function () {
        return 'this is from BaseStringGetter';    
    }
}

function DerivedStringGetter() {
    this.showCombinedStrings = function () {
        console.log( 'this is from DerivedStringGetter and... ' + this.getString() );
    }
}
DerivedStringGetter.prototype = new BaseStringGetter();
var stringGetterInstance = new DerivedStringGetter();

function Unrelated() {};
var unrelatedInstance = new Unrelated();
unrelatedInstance.stringGetter = stringGetterInstance.showCombinedStrings;
unrelatedInstance.stringGetter();

3 Answers 3

1

One option is this:

unrelatedInstance.stringGetter =
    stringGetterInstance.showCombinedStrings.bind(stringGetterInstance);
unrelatedInstance.stringGetter();

Here, you're using Function.prototype.bind() to make this inside of unrelatedInstance.stringGetter() always refer back to stringGetterInstance.

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is how you are calling unrelatedInstance.stringGetter();

Even though stringGetter refers to the showCombinedStrings function, this inside showCombinedStrings now refers to the unrelatedInstance instance which does not have the toString() property that is why the error.

Demo: Fiddle

Here the value of this is printed as Unrelated {stringGetter: function} which is not an DerivedStringGetter instance


One easy solution is to use .bind() to give a custom execution context to unrelatedInstance.stringGetter like

unrelatedInstance.stringGetter = stringGetterInstance.showCombinedStrings.bind(stringGetterInstance);

Demo: Fiddle

Now even if you call unrelatedInstance.stringGetter(), this inside showCombinedStrings will refer to the stringGetterInstance instance.

Comments

0

When you call a function on an object, this will refer to the object the function is invoked on even if the function was originally defined elsewhere.

When you call unrelatedInstance.stringGetter();, this inside the function will now refer to unrelatedInstance which doesn't have getString(). The MDN this reference page has more info.

You could do something like this to preserve the original context:

unrelatedInstance.stringGetter = function() {
    return stringGetterInstance.showCombinedStrings();
}

Edit: I left out bind that the other answers have now mentioned since it doesn't exist in IE8 but you'd be fine using that if you have a shim or don't care about old browsers.

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.