tester
tester

Reputation: 23159

Is using a cached "this" faster than "this" when accessing methods of the same object?

if I access this.something multiple times from another method, would it be faster to cache "this" and access something() or should I just use this.something() over and over?

<script type="text/javascript">
var Foo = (function() {
    return {
        something: function() {
            // Do something
        },
        stuff: function(obj) {
            this.something(obj);
            // ...
            this.something(obj);

            /* OR should I cache this? */
            var $that = this;
            $that.something(obj);
            // ...
            $that.something(obj);
        }
    };
}());
</script>

Upvotes: 0

Views: 166

Answers (4)

6502
6502

Reputation: 114481

I don't see why a variable should be faster than this.

Something that could have been possibly faster but that I found does NOT work is to cache the whole method lookup... e.g. by doing m = object.method; ... m(x,y,z);. This is something that for example in Python works (because of the bound method concept) but that however is not available in Javascript.

The result of a method lookup in Javascript gives you more or less something like what is a method pointer of C++, in other words a function that doesn't know this and so you must provide this yourself it to be able to call it.

The only difference is that in C++ any method that's not declared static will not be callable without providing a this, while in Javascript saving the method lookup may apparently work only for methods that at runtime don't need this perform as expected.

For example var mycos = Math.cos; mycos(0.3); on chrome at least apparently works because cos doesn't need to access Math (not really that surprising after all).

You can get a closure that functionally works as a cached method...

var cachedfoo = obj.foo;
var foo = function(x, y, z) { return cachedfoo.call(obj, x, y, z); }
...
foo(1,2,3); // this is the same as obj.foo(1,2,3)

that could be useful for other reasons, but that IMO it's not going to be faster (it would probably be slower indeed)...

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816442

Update: Check CMS' comment below for the real truth (but I don't think it changes anything regarding performance).


Approximate truth:

No, it won't make any difference. Upon execution of the function, an activation object is created and put at the beginning of the scope chain of the function (more specifically, its execution context).

The activation object has the properties this, arguments, one property for each parameter passed and for each variable declared in the function.

Hence, this and $that live in the same scope and you gain nothing from it. You only get an improvement, when you reference an object/value locally that is in a higher scope.

  +-------------------+     +-------------+
  | Execution Context |  +->| Scope Chain |
  | ----------------- |  |  | ----------- |
  | Scope chain  +----+--+  | 0    |  +---+----------+
  +-------------------+     | 1    |  +---+-...      |
                            +-------------+          |
                                                     |
                                                     |
                                                     |
                            +--------------------+   |
                            |  Activation Object |<--+
                            | ------------------ |
                            | this     |  foo    |  (if called with foo.method())
                            | arguments|[someObj]|
                            | obj      | someObj |
                            | $that    |  foo    | (undefined until assignment)
                            +--------------------+

Graphic stolen from High Performance JavaScript. It's an interesting book to read.

Upvotes: 5

Arnaud Le Blanc
Arnaud Le Blanc

Reputation: 99921

Only profiling will answer here. But before doing such micro-optimizations, ask yourself if you really need to.

Upvotes: 0

Chris B. Behrens
Chris B. Behrens

Reputation: 6295

You'll just be pointing at a copy of a reference to an object, rather than directly to the reference to the object. I can't imagine how caching it would be faster - but hey, fire up a test framework, execute it inside a loop 10000 times and see if it makes any difference.

Upvotes: 3

Related Questions