11

In the example below, when functionA() is invoked, the this keyword refers to the containing object, so I can access its properties (e.g. theValue)

My question: How do I refer to properties of myObj from within the nested functionB()?

var myObj = {
    theValue: "The rain in Spain", 
    functionA: function() {
        alert(this.theValue);
    },
    moreFunctions: {
        functionB: function() {
            alert(????.theValue);
        }
    }
}

myObj.functionA(); 
myObj.moreFunctions.functionB();  

Thanks in advance.

3 Answers 3

10

Immediate invocation to the rescue!

var myObj = (function () {
    var that = {
        theValue: "The rain in Spain", 
        functionA: function() {
            alert(this.theValue); // or that.theValue, both work here
        },
        moreFunctions: {
            functionB: function() {
                alert(that.theValue);
            }
        }
    };
    return that;
}()); // <-- immediate invocation !!

You can decompose it even further:

var myObj = (function () {
    function functionA() {
        alert(that.theValue);
    }
    function functionB() {
        alert(that.theValue);
    }
    var that = {
        theValue: "The rain in Spain", 
        functionA: functionA,
        moreFunctions: {
            functionB: functionB
        }
    }
    return that;
}());

If you're familiar with OOP, you can use this to make private variables.

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

1 Comment

I'm confused about which answer to accept. elclanrs' suggestion (alert(myObj.theValue);) works (with no refactoring required), but Frits' solution (and a bit more research) has provided me with information on closures, immediate invocation, & how this can be used to make private variables, so I'm accepting this answer on that basis. Thanks everyone.
6

You can simply use myObj:

alert(myObj.theValue);

Check demo http://jsbin.com/izugon/2/edit

Comments

3

A common practice is to define a "self" variable and use that rather than the this keyword. This helps when you wish to add scope or create a class.

var myObj = new function(){
    var self = this;
    this.theValue = "The rain in Spain";
    this.functionA = function() {
        alert(self.theValue);
    },
    this.moreFunctions = {
        functionB: function() {
            alert(self.theValue);
        }
    }
   }();

   myObj.functionA();
   myObj.moreFunctions.functionB();

Another possibility is to use the ECMA5 Function.prototype.bind method. To put it simply, you can bind a method's this keyword. Follow the link or use a search engine for more details. If you use this method, beware that it is not compatible with older browsers, but the provided link shows an alternate implementation you may use to implement the .bind method in older browsers.

var myObj = new function(){
    this.theValue = "The rain in Spain";
    this.functionA = function() {
        alert(this.theValue);
    }.bind(this);
    this.moreFunctions = {
        functionB: function() {
            alert(this.theValue);
        }.bind(this)
    };
}();

myObj.functionA();
myObj.moreFunctions.functionB();

4 Comments

Nop: jsbin.com/ofehap/1/edit, this in there is window. this applies inside functions, and the context depends on how you call that function.
I think you're missing the point. After your edit it'll work but you've just changed the data structure. Plus the option with bind will not work because this is still window.
You are right, when I originally read this I had a function in mind, rather than a simple clean JSON structure. I fixed the code to make it work as I originally intended, but I do not recommend it as the answer if you want to keep it clean JSON. However, the scoping does make it more attractive.
I'll remove the down vote for the effort, but you've said it already, this is not a great answer. For the scoping you can just use a module pattern approach like the answer by @FritsvanCampen.

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.