Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does 'this' work in JavaScript?

I know there are several other posts on this topic but they still leave me confused.

I've included jQuery and everything and, I have a simple javascript class like this example:

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph=fillKph;
}

function fillKph(){
  $("#kphdiv").html(this.speed*1.61);
}

car1 = new CarConstructor();
car1.fillKph();

Now I know that that code snippet doesn't work and is not properly consturcted.

The "this" keyword there is referencing my dom element with the id of "kphdiv".

The question I have is what is the best way to handle this.

Ive seen one method where you set some variable equal to this (binding it) and then use that variable to reference your object. For example:

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph=fillKph;
}

function fillKph(){
  var me=this;
  $("#kphdiv").html(me.speed*1.61);
}

car1 = new CarConstructor();
car1.fillKph();

I could also make the me a global variable ... I don't know.

I was just curious if there is another/better way.

like image 891
Travis Avatar asked Dec 14 '22 03:12

Travis


1 Answers

Oh boy, you are confusing quite a few things.

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph; // <-> This particular statement has no meaning. 
  //When you write this.fillKph without any assignment, it will be 'undefined'. 
  //Just because you have a function named 'fillKph' somewhere else, 
  //it doesn't mean it will get attached to this property.
}

Try,

var toyota = new Car();
alert(typeof toyota.fillKph); //will alert undefined.

The fillKph function is created in global scope, i.e. as property of 'Window' object.

function fillKph(){
  var me=this;
  $("#kphdiv").html(me.speed*1.61);
}

To fix it, you can what rezzif suggested. Your final code will look like

function Car()
{
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph = function (){
      $("#kphdiv").html(this.speed*1.61);
  };
}

car1 = new Car();
car1.fillKph();

If you notice, I did not store reference to 'this' inside a local variable. Why? There is no need in this scenario. To understand more, see my detailed answer here.

If you are going to create lot of Car objects, you can define the fillKph method on the prototype.

function Car()
{
  this.speed=19; // in mph
  this.make="Ford";
}

Car.prototype.fillKph = function fillKph() { $("#kphdiv").html(this.speed*1.61); };

car1 = new Car();
car1.fillKph();

EDIT:

If you do something like,

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph = fillKph;
}

function fillKph(){
  $("#kphdiv").html(me.speed*1.61);
}

car1 = new Car();
car1.fillKph(); //This will work as expected.

But the problem is that fillKph is defined in 'Window' scope, so I can directly call it like,

fillKph(); //Calling it this way will break it as it won't get correct 'this'.

Point is,

alert(typeof fillKph); // alerts 'function' if you do it your way,
alert(typeof fillKph); // alerts 'undefined', if you do it the way I suggested, which is preferred in my opinion.
like image 91
SolutionYogi Avatar answered Dec 26 '22 11:12

SolutionYogi