3

I have a bit of a confusion on the term var and declaring a variable with keyword this in a JavaScript constructor function. For example, in the code below, is var title a different variable than happySongs[0].title. They are both initialized with something different. title is initialized in the constructor to song parameter and title is also initialized outside the constructor function. However, they both return something different. If you print out happySongs[0].title it gives you the new value. However, if you print out the concat() method, title will not have the new value of 'test', but rather the old one.... So there are two different things going on here? Are these separate variables? Is there a difference when you declare a variable with var and this inside a function constructor?

function Tune(song,artist) {
  var title = song;
  this.concat = function() {
   return title + " " + artist;
 }
}

var happySongs = [];
happySongs[0] = new Tune("Putting on the Ritz", "Ella Fitzgerald");

happySongs[0].title = 'test'
//prints out test
console.log(happySongs[0].title); 

 // prints out correct title and artist
console.log(happySongs[0].concat());
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user1142130
  • 1,617
  • 3
  • 20
  • 34
  • `var x` declares a variable, `this.x` is a property of the object. They're completely different. – Barmar Oct 23 '15 at 16:04
  • Possible duplicate of [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Jared Smith Oct 23 '15 at 16:04
  • yes, there is a difference which you have already demonstrated – Igor Oct 23 '15 at 16:05
  • Possible duplicate of http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript – TchiYuan Oct 23 '15 at 16:06

3 Answers3

0

var title is a local variable. this.concat = function() then "closes" over the title/artist variables. this.title and [0].title are properties of the object.

ryachza
  • 4,460
  • 18
  • 28
0

They are different.

var title = song;

Is a locally scoped variable within the constructor function.

happySongs[0].title = 'test'

Is creating a title property on the constructed Tune object. Changing one will have no affect on the other. The concat function, being declared within the constructor function, has access to the locally scoped title variable declared in the outer scope. If you reference this.title instead, you would get the property:

this.concat = function() {
  return this.title + " " + artist;
}

The above, if placed in your original code, would cause the final line:

console.log(happySongs[0].concat());

To output "test Ella Fitzgerald".

James Thorpe
  • 31,411
  • 5
  • 72
  • 93
0

is "var title" a different variable than "happySongs[0].title"

Yes, they are different variables. The reason for the confusion, I think, is on the line

happySongs[0].title = 'test'

Before that line is executed, happySongs[0] does not have a public "title" property.

When you declared var title = song from within the "constructor", you created a locally scoped variable. The tricky part is that, when you created the concat function, JavaScript creates what's called a "closure". A closure is basically a grouping of a function and it's environment. In order for concat to run, it needs to know what the variable "title" has. So whenever concat is called, it looks at that variable. It doesn't matter when the function is called, it will always look at that local variable. Even if it's technically "out of scope".

After calling happySongs[0].title = 'test', you've created an actual public property on that object named "test". This property can be accessed from outside of the object whenever you want, but it won't change the concat function because the concat function is in it's own closure (looking at the local title variable). Note that, if you made the concat function like

return this.title + " " + artist;

with the "this" keyword, then the concat function would look at the public property on the object (which you'd be able to change at a later time).

You can think of the var title = song; line as creating a "private" property. It's only accessible from within the object. This is definitely a simplified way of looking at it. If you want to understand more about what's happening, you have to understand JavaScript scoping and closures.

http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

Carlos Rodriguez
  • 2,190
  • 2
  • 18
  • 29