Question

I'm trying to create encapsulated objects that can be inherited and that possess some public properties. Here's some code:

var MyObject = (function()
{
    function myObject()
    {
        //Public variables
        this.publicVar1 = 'hello';
        this.publicVar2 = 'world';
    }

    function foo()
    {
        console.log(this.publicVar1 + ' ' + this.publicVar2);
    }

    function bar()
    {
        foo();
    }

    //Public API
    myObject.prototype = {
        constructor: myObject,
        foo: foo,
        bar: bar
    }

    return myObject;

})();

var mo = new MyObject();
mo.foo(); //hello world
mo.bar(); //undefined undefined

My question why exactly does mo.bar() log 'undefined undefined' and how can I fix this issue?

I'm trying to keep publicVar1 and publicVar2 in scope internally to the MyObject module but also make them publicly accessible and inherited by any other objects that extend the myObject prototype.

Thanks.

Was it helpful?

Solution

When bar calls foo() it is calling a function that is not a member of any object and the "this" keyword inside that function is referring to the window object.

This would work:

function bar()
{
    this.foo();
}

EDIT

Your code could be quite easy to misunderstand for someone trying to understand scope. Keep in mind that when you are calling mo.foo() and mo.bar() and this.foo() (inside the bar function) you are referring to the properties you have declared on the prototype, NOT the names of the functions you have declared inside your module. It's just a coincidence that they happen to be the same name.

The below code would illustrate it a little better:

var MyObject = (function()
{
    function myObject()
    {
        //Public variables
        this.publicVar1 = 'hello';
        this.publicVar2 = 'world';
    }

    function moduleFooFunction()
    {
        console.log(this.publicVar1 + ' ' + this.publicVar2);
    }

    function moduleBarFunction()
    {
        this.foo();
    }

    //Public API
    myObject.prototype = {
        constructor: myObject,
        foo: moduleFooFunction,
        bar: moduleBarFunction
    }

    return myObject;

})();

var mo = new MyObject();
mo.foo(); //hello world
mo.bar(); //undefined undefined
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top