

Understanding JavaScript function invocation and "this" - wycats
http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/

======
tomp
The handling of the _this_ argument is of crucial importance in the design of
programming languages with first-class functions that feature some kind of
objects, i.e. data with attached behavior (call them functions or methods).

There are basically 3 possibilities that I see:

\- _differen invocation syntax_ , with _explicit this parameter_ Lua is an
example of a language that uses this approach:

    
    
      table.method1(arg1, arg2, arg3)
      table:method2(arg2, arg3, arg4)
    

Here, method1 is called with 3 parameters (without the _this_ parameter), but
method2 is called with 4 (the first parameter is the _this_ object, table).

This is undoubtedly the approach with the most efficient execution, but it
places a huge burden on the programmer, as one has to distinguish methods from
ordinary functions both at call site, and at definition (if you attach a
normal function to a table and invoke it as a method, you have a problem if
the function doesn't expect the first parameter to be _this_ ). Also, this
approach is the opposite from the one found in the traditional OOP languages
such as Java and C++.

\- _automatic method binding_ Python is an example of a language that uses
this approach:

    
    
      f = obj.method
      f(arg1, arg2)
    

In this case, the function f is called with the first parameter being _self_ ,
the Pythonic _this_. In Python, the _self_ parameter (Pythonic _this_ ) is
declared explicitly at method definition, but I believe that it could also
work if it were implicit.

This approach is perhaps the most sensible approach from the programmer's
point of view, where methods "just work" - you can call them using the normal
dot syntax, and you don't need to worry when using methods as first-class
functions - they will remember the object they were attached to.

However, a naive implementation of this technique is quite slow, as the
function must be bound to the _this_ object every time it is accessed. It is
possible to invoke (access and call at the same time) a method without this
overhead (e.g. use some object's internal dictionary to check whether it has a
method with the appropriate name, and call it, passing _this_ as the first
parameter), but not when accessing attributes - one must check whether the
attribute is a method, and bind it to _this_ if it is. However, this is an
irrelevant argument in a language that supports arbitrary getters/setters
(which seems to be the direction that new OO languages are headed in).

Also, it complicates matters with ad-hoc objects:

    
    
      o = {}
      f = (arg1, arg2, arg3) -> arg1 + arg2 + arg3
      o.m = f
    

When we invoke the method _m_ of the object _o_ , do we pass _this_ as the
first parameter (where the function _f_ might no expect it) or not (loosing
the OO aspect)? Python conveniently avoids this matter by not supporting ad-
hoc objects out-of-the-box.

\- _implicit this_ Javascript is an example of a language that uses this
approach:

    
    
      f = (arg1, arg2) -> print this, arg1 + arg2
      f(1, 2)        // prints "undefined, 3"
      o.m = f
      o.m(1, 2)      // prints "o, 3"
    

Here, _this_ is an implicit, undeclared parameter of every function, and is
passed at every call/invocation (if a function is called like in the second
line, _this_ is set to the global object _window_ in the browser, or to
_undefined_ in strict mode). Here, there is some overhead at every unbound
function call, as an extra parameter is passed, and it is not clear how this
overhead can be avoided (except by avoiding plain function calls, and sticking
to OOP). Ad-hoc object creation is simple, as functions/methods have a simple
way of knowing whether they were called (without a _this_ parameter) or
invoked (with a _this_ parameter). However, care must be taken when using
methods as first class values:

    
    
      f = o.m             // f will have the this parameter undefined
      g = o.m.bind(o)     // g will have o passed as the this parameter
    

A syntax extension would be nice, e.g.

    
    
      g = bind o.m
    

but it might be ambiguous. In my experience, this situation is not encountered
very frequently, so the trade-off is acceptable.

\---------------

I see all these possibilities lacking, but tend to consider the third solution
as the most favorable, mainly because it supports elegant and unambiguous ad-
hoc object construction. Maybe we could combine solutions 2 and 3, e.g. by
using getters on method objects that set _this_ automagically, but to keep ad-
hoc objects simple, an implicit _this_ seems to be a must, which means we
cannot avoid the overhead...

I'm sure I'm missing a very simple, straightforward alternative, and I would
be extremely grateful for any comments or constructive criticism.

------
aquark
I am fairly new to JS and have read a number of articles on how 'this' works
over the last few months after getting suitably confused by the (apparent)
'inconsistent' behaviour.

I think this is the best presentation of the concepts I've seen since it
builds everything up from the simplest primitives ... either that or I just
hit the critical number of repetitions to actually understand it!

~~~
kalid
I agree. The focus on "desugaring" and building up from the basics was key.
Most of the time we're using "conveniences" without knowing what was made
convenient!

------
neduma
Also refer this if you are new to JS - [https://developer.mozilla.org/en/A_re-
introduction_to_JavaSc...](https://developer.mozilla.org/en/A_re-
introduction_to_JavaScript)

~~~
fooandbarify
I don't know why your comment was downvoted - I found your link interesting,
if very basic. Certainly a well-written primer and it contains a decent
introduction to "this".

~~~
wqfeng
Yes. I also find this tutorial is great.

------
akdubya
The underscore.js source (<http://documentcloud.github.com/underscore/>) also
serves as a great primer on the effective use of 'this'. My rule of thumb is
to never rely on 'this' unless 1) the function is already bound to an object
or 2) I have explicitly set the binding via bind, call or apply. When in doubt
favor explicit argument passing.

~~~
wycats
In general, you can use explicit argument passing _or closing over what you
need_. I tend to use closures to get information from my current scope to a
callback, although that doesn't always work in heavily object-oriented code.

------
fnl
Quite good post; As I commented there - the only thing I think should be
there, too, is the pattern to make bind available in pre-ES5

