0

I'm having issues understanding scoping/access of fields defined with a JavaScript object.

Consider the following sample JavaScript object definition:

function SampleObject(controlName) {

    var _controlName = controlName;

    this.Display1 = function() {
        console.log(_controlName);
    }

    this.Display2 = function() {
        Display3();
    }

    Display3 = function () {
        console.log(_controlName);
    }
}

Now consider running the above object with the following example:

var a = new SampleObject("Bob");
var b = new SampleObject("Fred");

a.Display1();  //==> Displays "Bob"
b.Display1();  //==> Displays "Fred"

a.Display2();  //==> Displays "Fred"
b.Display2();  //==> Displays "Fred"

What I'm having difficulty understanding is how to access object fields (properties) from within private functions defined within my object. Within my example, I am confused as to why _controlName has the value "Fred" when it is displayed via Display2() for both objects a and b.

I suspect that is either an issue with how _controlName and/or Display3() is defined or I am unclear how scoping would work in this instance. Can someone please share some light on this?

Thanks,JohnB

4
  • Did you forget this in front of Display3? By omitting this, Display3 is global. Commented May 29, 2019 at 0:28
  • Ray Toal: Good point. But when I add "this." to Display3() definition, I get javascript errors saying that Display3() is undefined. Thoughts? Commented May 29, 2019 at 0:32
  • 1
    You have to add this in both places; the declaration and the call. Commented May 29, 2019 at 0:34
  • RCasburn: Thanks for pointing that out. But doesn't that then expose Display3() as a public method on that object? Is there no way to define it as a "private" method? Thx Commented May 29, 2019 at 0:44

2 Answers 2

2

In some other languages such as Java (where I hail from), when you are inside a method on an object, the this is implicit. In Javascript, this is NOT the case.

When you are assigning to this.Display1 and this.Display2, you are creating properties with those names on the object pointed at by this. Because of new, this is a different object each time.

However, what's happening when you assign to Display3 is that you are assigning to a global variable. If it doesn't exist, it is created for you. When you call new SampleObject("Fred"); the function which originally logged "Bob" is now gone, replaced by one which prints "Fred".

If you add 'use strict'; to the top of your SampleObject function, which suppresses this "implicit global" behavior, you get a reference error when you try to assign to the never-declared variable Display3.

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

Comments

1

Here's the explanation.

In the first call, new SampleObject("Bob"); the global variable Display3 gets set to a function that console-logs the value Bob.

In the second call, new SampleObject("Fred"); the global variable Display3 gets set to a function that console-logs the value Fred.

Now your Display1 is actually a method. Every object you create gets its own Display1 property. So Bob's Display1 logs Bob and Fred's logs Fred.

But because the Display2 methods each call the global Display3 method, they will all log what the function in the last assignment fo Display3 says to log, and that will always be Fred.

1 Comment

Thanks to you, Randy and ThisIsNoZaku for helping make this clear for me. I guess I was coming at it from a C#/VB.Net/Java mindset.

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.