Kanan Farzali
Kanan Farzali

Reputation: 1053

Issue with Javascript Classes

I am playing around with javascript, so it might sound as a trivial question. In a piece of code like this:

function timeFunction(fn, nameOfFn){
var start = Date.now();
fn();
var end = Date.now();
var time = end - start;
console.log(nameOfFn + ' took ' + time + 'ms');
}

function Person(name){
this.name = name;
this.sayName = function(){
    console.log(this.name);
}
}

var bob = new Person('bob');
timeFunction(bob.sayName,'sayName');

Output is:

result
sayName took 7ms 

(time will differ everytime you run the code)

Not sure where 'result' comes from and why 'Bob' is not shown.

Upvotes: 0

Views: 75

Answers (2)

Fabrizio Calderan
Fabrizio Calderan

Reputation: 123387

Bob is not shown because of the different scope of this inside sayName method: try

function Person(name){
   var _this = this;

   this.name = name; 
   this.sayName = function(){
      console.log(_this.name);
   }
}

or, even better, use bind() as also suggested by @nnnnnn in a previous answer.

(and I can't see the "result" string when I execute your code, maybe it comes from another piece of code)

Upvotes: 2

nnnnnn
nnnnnn

Reputation: 150030

Within your sayName() function this is not what you are expecting. It's actually window, and so you are logging the window.name property (which happens to be "result" in your case - I would guess you're testing your code in jsfiddle?).

That's because this in JavaScript is set according to how a function is called, it's not automatically whatever object the function "belongs" to. (In fact, functions don't really "belong" to objects at all - your bob object doesn't "own" .sayName(), it just has a reference to it.)

MDN explains this in detail.

One way to get your code to behave the way you expect is to use the .bind() method:

timeFunction(bob.sayName.bind(bob),'sayName');

Upvotes: 4

Related Questions