thefuzzy0ne
thefuzzy0ne

Reputation: 481

Javascript: Unable to access public prop from private method

Quick question.

I've been using jQuery (in moderation) for a long time, but I've never really had much experience with "classes" (used loosely).

Here is my test "class", available at http://jsfiddle.net/TxUs2/.

function MyClass(prop) {
    this.prop = prop;

    var init = function()
    {
        alert(this.prop);
    }

    init();
}

var myClass = new MyClass();

I want the init() method to be private. Please could someone briefly explain why I am unable to access a public property from a private method?

I'm assuming it has something to do with 'this' essentially pointing to the method itself from within the method, and not the containing function (or "class"). How do I get around this?

Many thanks in advance.

EDIT: Many thanks for all of your input. All answers were excellent. :)

Upvotes: 1

Views: 57

Answers (2)

Frédéric Hamidi
Frédéric Hamidi

Reputation: 262979

In your current code, init() is a "free" function. If you call it naturally, within its body this will be set to the global object (or to undefined in strict mode).

You could make it a method by writing:

this.init = function() {
    alert(this.prop);
};

this.init();

Or you could use call() or apply() to provide the context at call-time:

var init = function() {
    alert(this.prop);
};

init.call(this);

Upvotes: 3

James Allardice
James Allardice

Reputation: 165971

The problem is that when you invoke init it's being called with no context and therefore this does not refer to an instance of MyClass. You can solve this by saving a reference to this in the constructor, calling init in the context of this or binding init to this:

  • Saving a reference to this:

    function MyClass(prop) {
        this.prop = prop;
    
        var that = this;
        var init = function() {
            alert(that.prop);
        }
    
        init();
    }
    
  • Calling init in the context of this:

    init.call(this);
    
  • Binding init to this (which makes every call behave like init.call(this)):

    var init = function () {
        alert(this.prop);
    }.bind(this);
    
    init();
    

Upvotes: 4

Related Questions