1

I was trying to understand the scope of variables in javascript objects. But the behavior that I am getting seems to be a little off the road. To put it simply, if I have an object that defines a function as a variable, then the function variable is not able to access other variables of the object in which it is defines. The code below will make things clear.

<html>
<head>
    <script type="text/javascript">

        var someObject = {
            someVariable : 5,
            getVariable: function() {
                return someVariable;
            }
        };

        window.onload = function () {
            alert(someObject.getVariable());
        };

    </script>
</head>
<body>
    Hello There
</body>
</html>

The above code gives "ReferenceError: someVariable is not defined" for the someVariable in function getVariable(). Would anyone like to comment on this behavior?

2
  • 2
    In your code someObject is a variable that points to an object. But someVariable is the name of a property on that object. Variables and object properties are very different things. Commented Nov 6, 2012 at 1:25
  • Property resolution and identifier resolution are very different things. The first is resolved as properties of an Object and proceeds along the [[Prototype]] chain, stopping at null. The second is resolved as local parameters of an execution context and proceeds along the scope chain, which is a sequence of execution contexts (Lexical Environments) stopping at the global object. Commented Nov 6, 2012 at 1:36

3 Answers 3

3

Absolutely.

The "variable" you're talking about isn't a "variable", it's a property of an object (the object happening to be a variable).

As such, you have two options.
Assuming that your object is made like this:

var obj = {
    property : 42,
    everything : function () { /* ... */ }
};

The two options for inside of your function body, to return the value 42 are:

obj.property;

OR

this.property;

When you call:

obj.everything();

The JS interpreter will see obj as being equal to this inside of the function.
Or you reference obj itself, directly, and access property using either .property dot-notation, or ["property"] bracket-notation.

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

15 Comments

this will reference the object only if the function is called in a way that sets its this to be the object (e.g. obj.everything()). The function can be called so that its this is a reference to any object (or in strict mode, any value), even null or undefined, e.g. var x = obj.everything; x();.
Absolutely. Dynamic resolution of this and its late-binding are, I felt a little too far down the path for somebody becoming familiar with object properties, on the ground floor. While it can be a powerful tool, AND has to be carefully guarded for things like callbacks (where pre-emptive binding becomes important), I think just the warning that x = obj.func; x(); throwing horrible errors is enough for now.
I don't see that warning. Your answer (and others) introduce this when the question was about confusion over the difference between identifier resolution of environment variables vs object properties. The simple answer is to use return someObject.someVariable; and leave this out of it. But that horse has bolted. :-)
I agree with @RobG. You should generally avoid this since its value depends on the execution context. It might work for one-off uses, just as the obj.property construct. However, if this is supposed to be a general usage form, then one should define a class instead and she will not have the problem in the first place.
@RobG, Norgaurd You are absolutely correct about using someObject.someVariable instead of "this.someVariable". As you pointed out, this.someVariable will work only when the getVariable is invoked directly on someObject. Although, I couldn't really understand the technical explanations, I still now get a hang of it. Thanks all for sharing your experiences and ideas.
|
1

That is not a variable, that is a property/field of an object.

Try this.someVariable.

Here this is a (rather special) variable that points to the object, and the dot (or square bracket) syntax can be used to access fields of that object.

You can also do someObject.someVariable in places where someObject (another variable pointing at the object) is in scope.

Comments

0

Try this.someVariable:

var someObject = {
        someVariable: 5,
        getVariable: function () {
            return this.someVariable;
        }
    };

window.onload = function () {
    alert(someObject.getVariable());
};

3 Comments

You are correct, but basically I was trying to understand why adding "this" works? Why can't the function access the someVariable directly as it seems to be in scope of the function.
@Nirvan Because it's not a variable, but a property of the object.
@Nirvan—using this only works if the function is called in a way that sets its this as a reference to someObject, e.g. someObject.getVariable(). It will not work (for example) if assigned as a listener: someElement.onclick = someObj.getVariable as in that case, when the function is called by the handler, its this will be set to the element.

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.