Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Rafael Rocha
Rafael Rocha
9,583 Points

Javascript Constructors.

Hi Guys,

When I instantiate a variable inside a constructor, in that case, the width and height it doesn't get any value while trying to use inside some method.

But I can reach scene, camera, renderer applying new values to it inside methods.

Why does it happens?

// Couldn't get width and height values, but can set values.
function MyObj() {
    var scene, camera, renderer;
    var WIDTH = window.innerWidth;
    var HEIGHT = window.innerHeight;
}

// This code works, I can get the WIDTH and HEIGHT values inside some method.
function MyObj() {
    var scene, camera, renderer;
    this.WIDTH = window.innerWidth;
    this.HEIGHT = window.innerHeight;
}

3 Answers

If you just use var inside a constructor, you're not really doing much. You're creating a variable that belongs to the scope of the constructor (function). That variable is not linked in any way to new instances of the object that you create when using new.

When you call a constructor (var myNewObject = new MyObj()), several things happen. First, a new object is created. Then it sets the constructor property of that new object to MyObj. It sets up the prototype so that the newly created object can inherit properties from the constructor. Finally, it calls the constructor function inside the context of the newly created object.

So, whenever you use this inside the constructor, it refers to the object that's being created. That's why when you use this.WIDTH it works, as it should.

You should be using this in your constructors if you want to get properties from objects you create (and to access them from within methods).

Rafael Rocha
Rafael Rocha
9,583 Points

Just in case if I don't want to give a value like in my example, what should I do? Put it like: this.scene; this.camera; this.renderer; without receiving a value ?

You don't even have to mention them, you can just set them later on when you need them. You have an object, so you can add properties to it whenever you want to.

I'd like to provide an additional example. When I initially said that you're not doing much by declaring variables with var inside the constructor, I was oversimplifying things. What you are doing is basically creating a private variable by creating a closure. Methods can still use them. Here's a popular example:

function Dog(name) {
  var counter = 0;
  this.name = name;
  this.bark = function() {
    counter++;
    return "Woof!";
  }
  this.numBarks = function() {
    return counter;
  }
  this.greeting = function() {
    return "My name is " + this.name;
  }
}

var fluffy = new Dog('Fluffy');
fluffy.name; // "Fluffy"
fluffy.bark; // "Woof!"
fluffy.bark; // "Woof!"
fluffy.color = "brown";
fluffy.color; // "brown"
fluffy.greeting(); // "My name is Fluffy"
fluffy.numBarks(); // 2 - because you called bark() 2 times.
fluffy.counter; // undefined
Rafael Rocha
Rafael Rocha
9,583 Points

But if I create the same object like this:

Where should I create my Global var counter??

var counter = 0; // HERE?

function Dog(name) {
   var counter = 0;// HERE? Probably not!
   this.name = name;
}

Dog.prototype.bark = function(){
    counter++;
    return "Woof!";
}

Dog.prototype.numBarks = function(){
    return counter;
}

Dog.prototype.greeting = function(){
    return "My name is " + this.name;
}

var fluffy = new Dog('Fluffy');
fluffy.name; // "Fluffy"
fluffy.bark; // "Woof!"
fluffy.bark; // "Woof!"
fluffy.color = "brown";
fluffy.color; // "brown"
fluffy.greeting(); // "My name is Fluffy"
fluffy.numBarks(); // 2 - because you called bark() 2 times.
fluffy.counter; // undefined

Thanks

If you add methods that way, you'll lose the convenience of a closure and won't be able to create 'private' variables. And even if you pollute the global scope with a counter variable, it won't be scoped to each instance of Dog, instead they'll share it, so you'll get a number of how many barks all instances of Dog did.

What you can do is this:

function Dog(name) {
   this.counter = 0;
   this.name = name;
}

Dog.prototype.bark = function(){
    this.counter++;
    return "Woof!";
}

Dog.prototype.numBarks = function(){
    return this.counter;
}

Dog.prototype.greeting = function(){
    return "My name is " + this.name;
}

But then, the counter property will be accessible, so the numBarks method is not needed anymore:

var fluffy = new Dog('Fluffy');
fluffy.counter; // 0
fluffy.bark(); // "Woof!"
fluffy.counter; // 1
fluffy.numBarks(); // 1

I think you need parentheses at the end of your methods.

innerHeight(); innerWidth();

Rafael Rocha
Rafael Rocha
9,583 Points

Thanks for your feedback, Austen. But it isn't the problem. I was just asking about how do I create a var that could be accessible inside methods, in that case this var belongs to the object, and I want to use inside the methods.