
JavaScript: what is "this"? - juvenn
http://howtonode.org/what-is-this
======
WilliamLP
If anyone wonders why every JavaScript framework under the sun rolls its own
object system, and they're all incompatible, and almost nobody uses native
JavaScript alone anymore, this is one of the reasons.

~~~
vr
The reason why some frameworks roll out custom object systems is because they
try to make JavaScript look like a language with classes, "this" semantics
isn't what's driving them. In a language with classes developers are used to
"this" being an instance of the current class, and this expectation creates a
consfusion in JavaScript. If you don't look at it through the prism of
classes, the rule for "this" is pretty simple: "this" is the receiver. Create
a function, apply it to any object, and that object will be the receiver
available as "this". It's that simple. Now the only confusion left is who's
the receiver. In "foo.bar()" like cases it's obvious, and the only remaining
case (if you don't count the discouraged "with" statement) is "bar()" which
calls a function on the global object (like in Python).

~~~
natrius
You've left out event handlers, which are another case in which `this` can get
confusing.

------
tumult
_It's not entirely our fault, the language was designed to work like one thing
(scheme-like), but look like another (c-like)._

The baseless assertion rears its head again. People keep repeating this, and
it's not true. JavaScript is not Scheme. It's not any more Scheme-like than
Java, C++, Python, Perl, or many other languages. Lua and Ruby are far more
Scheme-like than JavaScript.

I've commented before on people repeating this statement without ever
examining it. I don't want to dredge up the arguments against it again (
<http://news.ycombinator.com/item?id=1171202> ), mostly I just want to whine
at it because it's so annoying. Why do you have to make JavaScript seem like
something it's not? Are you trying to seem cooler by equating the language you
work in to Scheme? What's wrong with JavaScript just being what it is?

~~~
audionerd
I think the author is just citing how influential Scheme was to JavaScript's
design.

In "Coders at Work", page 141, Brendan Eich talks about wanting to build a
scheme-like language for the browser. The c-like syntax was adopted because
Netscape wanted it to look like Java.

~~~
tumult
Maybe he wanted to. If that was his goal, I think he failed.

    
    
        Scheme: First-class functions, tail-call elimination, macros,
                hygienic macros, write and parse the AST directly.
        JavaScript: First-class functions.
        
        Scheme: Immutable arrays and lists, mutable strings.
        JavaScript: Mutable-only arrays, immutable-only strings.
    

Yes, I have, and have read, Coders at Work. I don't see how it's relevant.
JavaScript and Scheme share only one defining feature in common, first-class
functions. It's an important feature, no doubt, but many other languages have
it: C/Objective-C (with Apple's blocks extension), C++ (with Boost.Lambda),
Perl, Python, Ruby, Lua, Io, OCaml, ML, Haskell, the list goes on. People
compared Perl to Lisp once, briefly, when it was one of the few dynamic
languages, but they don't anymore.

~~~
avibryant
They share only one defining feature? Bullshit. If we include "garbage
collected", that gets rid of C and C++. If we include "dynamically typed",
that gets rid of OCaml, ML, Haskell. If we include "single namespace for
functions and variables", that gets rid of Ruby, Io, and Perl. Now we're down
to JavaScript, Python, and Scheme, which, yes, are all in basically the same
family of languages. If we include the (admittedly subjective) feature "small
language spec", that gets rid of Python, and we're left with JavaScript and
Scheme as the only two mainstream languages with those particular defining
features.

If I were describing JavaScript to someone who was a programming language
expert but somehow was never exposed to it, I would describe it as "Scheme,
with C syntax, no tail calls, and a strange prototype-based object system".

------
rriepe
I had a lot of trouble with this as a newbie to Javascript. Glad to see it
posted, even if it's months and months late for me.

------
sesqu
_The var statement declares a variable as local to the current scope and the
entire current scope, not just from the var statement onward. These local
variables shadow any existing variables from outer scopes._

Err, I tested this on Chrome's Inspector console, and I don't see such
behaviour. The article says _name_ should be undefined at the time of the
comparison in the below code, but it isn't (and I frankly can't see why anyone
would want it to be). Is this a feature of my execution environment, or have I
just completely misunderstood what the author means?

    
    
      (function(name){var cmp=name=="tim"; var name; return cmp})("tim") // returns true

~~~
papercrane
Since the comparison happens before var is declared, it will always evaluate
to 'true'. I believe the author was thinking about something like so:

    
    
        (function(name) { var cmp = function() { return name=="tim"; }; var name; return cmp();})("tim");
    

This still evaluates to true, but I believe it has to do with the rules of
shadowing. If you change the declaration to 'var name="bob";' it will return
false.

------
icode
Honestly, I think this is all too complicated. In Javascript, when you look at
a line like this:

    
    
      a=1
    

you have to guess in which scope it changes or creates the variable a. I
prefer the way PHP is dealing with scope. You simply know that "a=1" is only
affecting the current scope.

~~~
IgorPartola
Which is why PHP is so much less flexible than JS. Also try this:

    
    
      $a = 1;
      function qqq() {
        global $a;
        unset( $a );
      }
      qqq();
      var_dump( $a );
    

P.S.: In PHP 5.1.6 calling unset() actually increases memory usage...

~~~
devinj
I find it hard to believe that the largest cause (or even a significant cause)
in the difference of flexibility of two languages is whether or not you can
declare variables to belong to a given scope, and to which scope they default
to.

~~~
IgorPartola
I was referring more to the "feel" of the language rather than the fact that
this individual feature is the single reason for why JavaScript is more
flexible.

------
btipling
This kind of a bind is available in dojo via dojo.hitch and in google closure
via goog.bind (make sure to require goog.base)

There's a $.hitch plugin in JQuery, it doesn't come with it by default.

------
endlessvoid94
[http://justin.harmonize.fm/index.php/2009/09/an-
introduction...](http://justin.harmonize.fm/index.php/2009/09/an-introduction-
to-javascripts-this/)

------
erlanger
I feel it's worth noting that JavaScript developers refer to "this" as the
_execution context._

------
nailer
It's this.

~~~
nailer
I appreciate that HN isn't Reddit, and expect that comment to be treated
appropriately, but somewhere I hope there's a Hacker who loves Faith No More
and just smiled.

