0

I see many people using the "this" keyword in an object oriented context in JavaScript. Similar to how "self" is used in Python and some other languages. In an object oriented context, I have been able to avoid using "this" by using the "module pattern".

For example:

var robot = (function() {
    // private variables
    var status = "on";
    var name;

    // private function
    function turnOff() {
        status = "off";
    }

    // public function
    function setName(new_name) {
        name = new_name;
    }

    return {
        setName: setName
    };
})();

Or, this pattern:

var robot = function(robot_name) {
    // private variables
    var status = "on";
    var name = robot_name;

    // private function
    function turnOff() {
        status = "off";
    }

    // public function
    function setName(new_name) {
        name = new_name;
    }

    return {
        setName: setName
    };
};

var FooBot = new robot('Foo');
var BarBot = new robot('Bar');

Is using "this" just a preference? Or, am I missing out on something?

Qix - MONICA WAS MISTREATED
  • 12,202
  • 13
  • 73
  • 131
RylonMcnz
  • 43
  • 11
  • Take a look at https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this – Aleksandar Đokić Aug 13 '16 at 18:21
  • 4
    Yeah, you are missing out on a lot of things. – Tiberiu-Ionuț Stan Aug 13 '16 at 18:21
  • It's a bit less OO-y, for one (while, arguably, better, it's still not as similar to other languages as using `this`). – BalinKingOfMoria Reinstate CMs Aug 13 '16 at 18:21
  • You don't have a constructor nor instances, so `this` is not useful. – Oriol Aug 13 '16 at 18:25
  • Possible duplicate of [How does the “this” keyword work?](http://stackoverflow.com/q/3127429/1529630) – Oriol Aug 13 '16 at 18:25
  • `this` is a preference in the sense that JS is *very* flexible, and so there are often several ways to accomplish a task. If you don't care about prototypal inheritance, and are satisfied with creating the same functions over and over every time you create an object, then you're fine. I personally wouldn't be satisfied doing that if there are many objects to create. –  Aug 13 '16 at 18:45
  • Notice that in both examples, `turnOff()` is most likely garbage collected since it is not referenced by anything after the closure is executed, and cannot be called. – Patrick Roberts Aug 13 '16 at 18:52
  • I only added turnOff() to show an example of a private function, one that might be called within robot. – RylonMcnz Aug 13 '16 at 18:57

1 Answers1

3

No, this is not a preference. this is useful to know on which object your function was called.

In your example you don't need this information, that's why this is not useful for you.

But consider a constructor with multiple instances, and each one has its own associated data:

class Robot {
  constructor(name) {
    this.status = "on";
    this.setName(name);
  }
  turnOff() {
    this.status = "off";
  }
  setName(new_name) {
    this.name = new_name;
  }
}
var robotFoo = new Robot('foo');
var robotBar = new Robot('bar');

How would you read and store the data of the desired instance without using this?

You could use static methods and pass the instance as an argument, but that would be uglier.

Oriol
  • 225,583
  • 46
  • 371
  • 457
  • Thank you for your response. I have edited my question to include a different pattern. Does this added pattern not behave as yours? I think I'm misunderstanding. – RylonMcnz Aug 13 '16 at 18:50
  • 1
    @RylonMcnz your added pattern creates new instances of the functions you defined for each object instance, whereas using classical prototypal inheritance ensures that all member methods are defined exactly once and used for all instances. To confirm this, check `FooBot.setName == BarBot.setName` in your second example vs. this example's `robotFoo.setName == robotBar.setName`. Your approach wastes a lot of memory if you make several instances of `Robot` – Patrick Roberts Aug 13 '16 at 18:56
  • Oh. That makes sense. – RylonMcnz Aug 13 '16 at 18:59
  • @RylonMcnz As @Oriol has pointed out in his answer, one way to define the functions once and still not use `prototype` and `this` is to define them as static functions like `setName(robot, new_name)`, much like C programs do, but it is certainly an uglier approach. – Patrick Roberts Aug 13 '16 at 19:03