0

So I have recently been learning about objects and methods in JavaScript and wrote this little example to help me understand things like "this" and methods a bit more.

objectTest = function() {
    this.test = 1;
    this.test2 = 2;
};

thisThing = new objectTest

thisThing.test3 = [1,2,3];

objectTest.prototype.whatIsThis = function(){
    console.log(this.test);
};

thisThing.whatIsThis();

The output of the above code is 1 which makes sense because it refers to the this.test, which i defined in the object.

Now what if i wrote objectTest like this:

objectTest = function() {
    var test = 1;
    var test2 = 2;
};

If i console.log(this); in my whatIsThis Method i will simply get: Object { test3=[3], whatIsThis=function()}

I am curious is there anyway for me to access the value of test and test2 without writing something like:

objectTest = function() {
    var test = 1;
    var test2 = 2;
    return "test is" + test + "and test2 is" + test2;
};

Also if this is possible what would be a practical example of needing to do something like this?

Andrew Font
  • 1,245
  • 3
  • 19
  • 38
  • 5
    No. Variables aren't directly tied to the instances being created. Properties are. `test = 1` actually [defines a global](http://stackoverflow.com/questions/1470488/what-is-the-function-of-the-var-keyword-in-ecmascript-262-3rd-edition-javascript), which is why it may seem to work once. But, you'll have collisions with every instance trying to set and use the same globals. – Jonathan Lonowski May 20 '14 at 20:00
  • Note, if you return a string from a function and then try to use that function with the `new` keyword, then you won't get that string back. You'll get an object. – Dancrumb May 20 '14 at 20:02
  • Ah right i should have used var. But would that change anything would i still be unable to access test and test2? – Andrew Font May 20 '14 at 20:04
  • @AndrewFont No, you wouldn't be able to access them elsewhere. Constructors act like any other function with regards to local variables -- they're only accessible within the `function` itself. The only way to extend access to them is [via closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Emulating_private_methods_with_closures). – Jonathan Lonowski May 20 '14 at 20:06
  • Do you have anything against using `this.test` inside constructor? If you're just trying out things and seeing what happens, then you've just seen that not using `this.varname` inside constructor function doesn't make those variables available in _instances_ of function created using `new` keyword. Are we missing something? – Ejaz May 20 '14 at 20:10
  • Yea this was a question of curiosity. I want to know IF it was possible. I have no applicable use for something like that. But thank you all for the answers =) – Andrew Font May 20 '14 at 20:12

1 Answers1

3

It's not really clear what you're asking, since your "What if?" example doesn't come with any justification.

However, you're nudging close to something interesting in JS and that's the implementation of 'private' variables.

For a prototype call objectTest:

objectTest = function() {
    var test = 1;
    var test2 = 2;
};

var ot = new objectTest();

test and test2 are, effectively, private variables, in that they are not accessible via the instance ot.

However, they're not accessible at all, so something like:

objectTest.prototype.getTest = function () { // ... };

can't be implemented, such that it provides access to test, since test is not a property of this when getTest is invoked against ot.

What to do... what to do?

Well, you could do this:

objectTest = function() {
    var test = 1;
    var test2 = 2;

    this.getTest = function () { return test; };
    this.setTest = function (val) { test = val; };
};

var ot = new objectTest();

These will work because test is available via a closure over getTest and setTest. test is still not a property of ot, so you have your private variable that can only be modified via your getter and your setter.

Update

The variables test and test2 are local to the function objectTest. That means, on each invocation of objectTest, they are created anew. Thus, new instances of objectTest objects do not share these values.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130
  • Ok, this makes allot of sense now. Out of curiosity, if i use 'ot.setTest(3)' from your example, am I changing the value of 'test' for all instances of 'objectTest'. So for example if I had 'ot2.getTest' would i return '3' or would i return the starting value of '2' – Andrew Font May 20 '14 at 20:16