2

I have a function defined on another function, like so

function Test(message) {
    this.message = message;
}

Test.prototype.print = function() {
    console.log(this.message);
}

Test.prototype.print.polite = function() {
    console.log(this.message + ', please.');
}

var x = new Test('hello world');

x.print();
x.print.polite();

x.print() prints 'hello world' as expected, but x.print.polite() prints 'undefined, please', as opposed to 'hello world, please'.

I understand that this is because the context passed to the print.polite function is the print function. Is there, however, a way to access the 'this' of print from print.polite, short of explicitly adding it as a parameter? I'd like to retain the invocation semantic of print.polite(), instead of making it printPolite().

I'm fairly new to JavaScript, so I apologize if this is an inane question.

Edit

Based on the suggestions, I've modified my code like so, and it seems to work.

function Test(message) {
    this.message = message;
    this.print.that = this;
}

Test.prototype.print.polite = function() {
    console.log(this.that.message + ', please.');
}

Like you pointed out, though, it is a rather hacky solution. Isn't there a more elegant way to do this?

1
  • That will set Test.prototype.print.that to the last created instance, so it will "work" only in that context, it will not work for the first n-1 instances. Commented Feb 19, 2015 at 9:05

2 Answers 2

1

You would have to use call or apply, like this:

Test.prototype.print.polite.call(x);

This calls the function Test.prototype.print.polite with x as the context, or this value, and no arguments.

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

Comments

0

It is possible to keep the invocation semantic, but the implementation may be a bit ugly.

function Test(message) {
    var local = this;

    this.message = message;
    this.print = function() {
        console.log(local.message);
    };

    this.print.polite = function() {
        console.log(local.message + ", please.");
    };

    return this;
}

Note that this does not take advantage of the prototype at all.

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.