32

I find this pattern all over the ExtJS source code.

method: function() {
  var me = this;
  ...
  me.someOtherMethod();
}

Why don't they just use this? Is there some advantage to always often defining me (outside of not having to type 2 characters)? I can understand if they are trying to maintain the context via closure, but it's done in places where there is no closure at all.

An example from Ext.panel.Panel:

disable: function(silent) {
    var me = this;

    if (me.rendered) {
        me.el.addCls(me.disabledCls);
        me.el.dom.disabled = true;
        me.onDisable();
    }

    me.disabled = true;

    if (silent !== true) {
        me.fireEvent('disable', me);
    }

    return me;
},
Hemlock
  • 6,130
  • 1
  • 27
  • 37
  • The only case I have ever used this sort of a practice is with new contexts. Can you provide a specific code snippet where it's not used in that fashion? – Steven Sep 15 '11 at 19:59
  • I hope people keep voting on answers for this. I picked Daniel's answer because he hit on it first and it fits the spirit of my question. – Hemlock Sep 15 '11 at 21:46
  • Maybe someone really doesn't like the idea of an implicit `this`? – Fake Name Sep 15 '11 at 22:20

10 Answers10

39

If your library is doing this in places where there are no embedded closures/callbacks that might have their own value of this, then this is just a "practice" or "style" or "convention" that they decided to follow in their methods. There is NO programming reason to always do it.

In the specific coding example you have now added to your question, there is no reason I'm aware of other than a common coding style. This code would generate the same result in slightly smaller code:

disable: function(silent) {

    if (this.rendered) {
        this.el.addCls(this.disabledCls);
        this.el.dom.disabled = true;
        this.onDisable();
    }

    this.disabled = true;

    if (silent !== true) {
        this.fireEvent('disable', this);
    }

    return this;
},

When there is a callback or closure involved, this is often done because there are callbacks used inside the method where they still want a reference to this, but those callbacks will have their own value of this so assigning:

var me = this;

or more commonly in other code I've seen:

var self = this;

is a way of retaining access to that object even in a callback that has a different value of this.

Here's a generic example:

document.getElementById("myButton").onclick = function () {
    var self = this;       // save reference to button object use later
    setTimeout(function() {
        // "this" is not set to the button inside this callback function (it's set to window)
        // but, we can access "self" here 
        self.style.display = "none";    // make button disappear 2 seconds after it was clicked
    }, 2000);
};
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 5
    That was my thought as well, but the OP himself made this observation that it's common practice to access `this` within callbacks. From my reading, he's asking specifically why it's also used when no new contexts are involved. – Steven Sep 15 '11 at 19:57
  • OK, I added a comment to my answer related to doing it when there are no callbacks/closures. A specific code example of one of those would have generated a more meaningful answer on that specific case. – jfriend00 Sep 15 '11 at 20:03
  • OK, I now commented on the specific code example added to the question. – jfriend00 Sep 15 '11 at 20:07
  • 4
    There is no _programming_ reason -- it's done for minification file size. `this` cannot be shortened, while `me` can. – Brian Moeskau Sep 15 '11 at 21:06
  • @bmoeskau - maybe, maybe not. Unless you know the developers, you can't know whether they're doing it for style reasons or for minification reasons. I've commented on the minification answers. Sometimes it saves you a few bytes, sometimes not - depends upon how many references to `this` within the function. – jfriend00 Sep 15 '11 at 22:16
  • 3
    @jfriend00, I'm not offering my opinion. I'm stating _exactly_ why this is done in Ext. – Brian Moeskau Sep 18 '11 at 06:52
  • Even if this wasn't answering the OP's exact question this is still a very valuable answer, especially because of that last example. Thank's @jfriend00 – Chris Schmitz Oct 13 '15 at 21:21
24

One reason is because with minification, me can become much shorter than this.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • 6
    when you minify code, me can become just 'x' or 'y' or something shorter than 'this'. Minifiers do not modify the 'this' keyword. – Hyangelo Sep 15 '11 at 20:07
  • So if they are going to use `this` more than ~3 times there would be some small advantage. Could be on to something here. – Hemlock Sep 15 '11 at 20:10
  • I think this is precisely the reason for it. Only other thing I could think of is to give a more descriptive name than `this` provides, though the `me` in the question code doesn't really offer that benefit. – user113716 Sep 15 '11 at 20:20
  • 5
    This does indeed sound like one possible benefit. With 12 chars to declare the minimized version `var a=this;\n` and a 3 char savings by using `a` instead of `this`, if there were more than four references to `this`, you would save bytes. If there were only one or two references to `this`, you would lose a few bytes. I do wonder if this is the real motivation though or if it's really just a common method implementation style to keep all methods consistent, even those with embedded closures. – jfriend00 Sep 15 '11 at 20:33
  • Yes, this is the main reason. In a large framework, this leads to significant change in minified file size. – Brian Moeskau Sep 15 '11 at 21:07
  • 1
    why didn't Javascript minificators just do this optimization? This reason seems dubious to me, this probably would probably only about 1-2% of file size, not worth manually obfuscating your original code for. – Lie Ryan Sep 16 '11 at 00:18
14

Besides the style reasons and the minification reasons, I decided to look at performance to see if this or self was any faster. I created this jsperf test.

As best I can tell, there is basically no difference in performance in any of the modern browsers that I tried or even IE6 bewtween using this vs. using a local variable like self or me. Chrome is ever so slightly faster with self and the others are too close to call. I think we can rule out any performance reasons. Here's a screen shot of the results I saw:

enter image description here

jfriend00
  • 683,504
  • 96
  • 985
  • 979
4

The problem is most likely connected to closure functions, for example as an argument when you register an callback. In that case "this" can have a whole different value, so they need to use "me" instead.

brain
  • 2,507
  • 1
  • 13
  • 12
4

It's done sometimes to maintain scope in a closure, but mostly (as in the posted example) to allow for minification as me can be minified down to one character, while this cannot be changed. After about 3 or 4 usages of this in a given function this becomes important (less than that and you might actually end up with a few extra bytes from the extra declaration code). It's as simple as that -- it has nothing to do with programming style or whimsy.

Brian Moeskau
  • 20,103
  • 8
  • 71
  • 73
2

Based on the Ext.panel.Panel example you just added, unless my understanding of Javascript variables is quite wrong, not making the assignment here would have absolutely no impact on what the code does.

The only possibility left is style.

While I would chalk this up as overengineering, it's useful to the extent that if you ever wanted to add a callback that required access to this in this context, you wouldn't need to go back to change all the this's to me's. After all, typing :s/ is hard.

Steven
  • 17,796
  • 13
  • 66
  • 118
2

Actually, though it probably isn't the motivation, doing this for style makes some sense. A lot of style conventions are to make it harder to forget something, such as always putting { } around an else block even if it's a single statement. Reassigning "this" would have a similar affect in that beginning JavaScript programmers would have closures "just work" a higher percentage of the time.

psr
  • 2,870
  • 18
  • 22
1

For the ExtJS framework specifically.

ExtJS has it's own mechanisms for handling problematic Javascript scoping, minification is the only reason for doing var me = this.

There are more details on the subject in this Sencha Forum thread.

James McMahon
  • 48,506
  • 64
  • 207
  • 283
1

While working ExtJs I didn't find this convention that useful. I didn't use closures very often. When working in other frameworks like AngularJs this convention has saved me much pain and suffering. Getting your scope wrong is a time consuming bug to track down. Once I started to use this convention, I never got the scope wrong again.

user3330270
  • 447
  • 4
  • 3
1

Outside of maintaining a context for use in closures I am not aware of any programmatic difference with using that pattern. Perhaps it is just a convention ExtJS is using.

Additionally, as noted by Daniel, it might be to shorten the code even further during minification. Libraries like ExtJS, jQuery, etc care a lot about file sizes and using this technique might yield enough file size savings

e.g. 1000 'this', assuming 1 char = 1 byte, is 4kb. Using the technique above can possibly shave off 2 or 3 kb.

update: Went ahead and did a small experiment..

var test = {
  a : function() {
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  },
  b : function() {
      this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  },
  c : function() {
      this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  }
}

minifies into

var test={a:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""},b:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""},c:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""}}

while

var test = {
  a : function() {
     var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  },
  b : function() {
      var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  },
  c : function() {
      var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  }
}

minifies into

var test={a:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""},b:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""},c:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""}}

which translates to about 10% more or less characters(of course it depends on how much 'this' is used repetitively in the block scopes of your code).

Hyangelo
  • 4,784
  • 4
  • 26
  • 33
  • Percentage change depends more on how much other code there is in the function. Your example has almost no other code so the percentage change will be magnified. We're talking about saving a smallish number of bytes per function, a max of 3 bytes per use of "this" when `this` is replaced by `a` after you've overcome the addition overhead of declaring `a`. – jfriend00 Sep 15 '11 at 21:00
  • As indicated in my answer the savings actually depend on how frequent you use the 'this' keyword inside each scope in your code. By this I mean how many times you can replace 'this' with 'me'. The number of occurrence by the 'this' keyword by itself does not determine the number of times you can replace it(e.g. 1 'this' in every function). – Hyangelo Sep 15 '11 at 21:24