8

In Javascript OO, when should I use the this keyword?

Also, if I want to call a method of a class from another method of the same class, should I use this or just the name of the function? E.g is this correct?

function Foo()
{
   this.bar= function()
   {
      alert('bar');
   }

   this.baz= function()
   {
     this.bar(); //should I use this.bar() or just bar()?
   }
}
Artem Barger
  • 40,769
  • 9
  • 59
  • 81
Ali
  • 261,656
  • 265
  • 575
  • 769
  • 1
    You cannot use just `bar()` because `this` is never implicit in JavaScript (since it's not really a proper object-oriented language.) `bar()` would first look for a variable defined as `bar` in the function `this.baz`, then it would look for a variable defined as `bar` in the function `Foo` and finally it would look in the global scope, and failing that it would throw an error. – Blixt Jul 17 '09 at 17:22
  • 1
    It's important to learn the JavaScript prototype system, so it's a great question to ask. But if I were going to do a large OO program in JavaScript, I'd use Joose.js or Js.Class. – Nosredna Jul 17 '09 at 17:23
  • There are some downvote trolls that vote down if they don't agree, or think silly, what is just wrong by the S.O. definition of downvote =\ – Fabiano Soriani Jul 19 '10 at 02:58

6 Answers6

6

When it comes to "object-oriented" JavaScript, here's a nice guide Mark Dickinson here on SO linked to: Private Members in JavaScript. It does go into detail about some other stuff you don't really need now, but once you understand how JavaScript works, you'll see that it's quite different from your ordinary object-oriented language when it comes to things like what this really means.

I'd say that in your case, you should definitely use this, but maybe your functions should be in the prototype part of your "class" (this avoids redefining the function every time a new instance is created.)

Blixt
  • 49,547
  • 13
  • 120
  • 153
  • I made a simple template for classes that seems to be very similar to what Douglas Crawford has in his article (that I linked.) If looking at code helps, you could always look at that: http://blixt.org/js/classes.js (raw file) http://blixt.org/js#project/js-classes (with syntax highlight) – Blixt Jul 17 '09 at 17:36
  • 1
    what do you mean by the 'prototype part of the class'? – Ali Jul 19 '09 at 13:20
  • 1
    Functions have a `prototype` property that is used as the prototype for objects created when calling the function with the `new` keyword. If you set `Foo.prototype.bar = function () {...};`, then all objects created with `new Foo()` will have a `bar` property that references the `Foo.prototype.bar` function. – Blixt Jul 19 '09 at 15:22
1

I have found 3 Ways to define a javascript class helpful.

Ali
  • 261,656
  • 265
  • 575
  • 769
0

In this particular instance, it's best to use a self-referencing variable in the place of this to prevent confusion and headaches inside functions.

function Foo()
{
   var self = this;

   this.bar= function()
   {
      alert('bar');
   }

   this.baz= function()
   {
     self.bar();
   }
}

The reason for it is because since everything in javascript is an object, the this keyword inside a function refers to the parent function. By defining a variable at a certain scope, your guaranteed that variable will maintain its scope.

TJ L
  • 23,914
  • 7
  • 59
  • 77
  • You do it so the scope is obvious. A lot of people use "that" instead of "self." – Nosredna Jul 17 '09 at 17:06
  • 2
    Note that by doing so, you're removing the possibility to rebind the function, i.e. `fooInstance.baz.call(barInstance);` – Blixt Jul 17 '09 at 17:15
  • @tj111: You said, "In your example, the call to this.bar() is referring to Foo.baz.bar, not Foo.bar". This is not true. If you create an instance of Foo and call baz then the context for baz is your Foo instance. Check it out: http://jsbin.com/onida/edit – Prestaul Jul 17 '09 at 17:19
  • You certainly need the self-reference in nested functions or where the function will be called in a different context - event handlers and deferred calls, for example. I try to avoid using it globally though. – glenatron Dec 24 '14 at 10:10
0

Just to stress and empathize previous answer of @tj111 I suggest you to read this. To better understand function scoping.

Artem Barger
  • 40,769
  • 9
  • 59
  • 81
0

The correct version is the one that doesn't give an error when you try to call the function. If you omit this you will get a ReferenceError exception.

sth
  • 222,467
  • 53
  • 283
  • 367
0

In another post about 'function aliasing' in JavaScript, I explained in detail, with examples, how 'this' works in JavaScript. I think it may be useful to you.

Please check: JavaScript function aliasing doesn't seem to work

Community
  • 1
  • 1
SolutionYogi
  • 31,807
  • 12
  • 70
  • 78