views:

344

answers:

8

I'm coming from a Java background, with its class-based inheritance model, trying to get my head around Javascript's prototype-based inheritance model. Part of what is throwing me off, I think is that I have Java's meaning of "this" solidly in mind - and Javascript's "this" is a very different beast. I understand that Javascript's "this" always refers to the function's caller, not the scope in which the function was defined - I mean, I have read that and understand superficially what it means. But I would like to have the understanding more deeply, and I think having another name for it would help. How do you think about JS "this"? Do you make a mental replacement every time you run across it? If so - what word or phrase do you use?

+5  A: 

I think JavaScript's this is much closer to Java's this than you think. In an OOP context, this means "this instance". I think what may be confusing about JavaScript's this keyword is that it can have different meaning depending on context.

Andrew Hare
"this" does not always mean "this instance". For example, you can manually set the value of "this" for any function by using Function.call or Function.apply.
Triptych
Right, so "this" means "this instance" until you change it. That doesn't change the initial meaning of "this". So am I safe to assume that you agree with me that "this" is highly contextual?
Andrew Hare
You really have to trust that 'this' is being set properly by the caller. Just like in objective-c I trust that 'self' is really the current instance. In Java you cannot change 'this' to point to something else.
Kekoa
@Andrew - "this" isn't just highly contextual. "this" *IS* context.
Triptych
@Triptych - I agree that it "is context" but the default context of "this" within an object is identical to Java's "this". The main difference is that in JavaScript the context can change whereas Java does not permit this. Just because something is contextual doesn't mean that you cannot make assumptions and learn about something based on its default context.
Andrew Hare
Javascript's default value of "this" is not identical to Java's in any case, since there are really no such things as class definitions in Javascript, and are certainly very different in the case of globally-scoped functions, which don't exist in Java, and in Javascript event handlers. I think your answer encourages people to make parallels that don't actually exist. Just my $0.02. I didn't even downvote.
Triptych
+1  A: 

How about 'JavaScript this'? It'd keep you tied directly to what you're doing and also provide the mental reminder that the concept of 'this' that you're currently working with is the JavaScript concept.

Eventually, I'd expect you'd stop calling it 'JavaScript this' and just call it 'this', being fully aware of what that means in the context you're working in. Which I'd expect is probably where you want to get to, anyway.

Ross Henderson
Yep. With apologies to Zen: Before you have learned Javascript, mountains are mountains; waters are waters. When I learned Javascript, mountains were no longer mountains and waters, no longer waters. Once I had mastered Javascript, mountains were again mountains and waters again waters.
Carl Manaster
+3  A: 

this isn't a function's caller (though it might be) or the scope in which the function was defined (though it might be) - it's the function's context.

The shifting meaning that @Andrew Hare refers to is probably closer to the source of your confusion; because of JS's prototype inheritance mechanism, the function keyword can mean, depending on how it's used, something closer to Java's class than Java's method definition.

Assuming execution in the browser:

var q = this.document; //this is window

var o = new (function pseudoconstructor(){
    this.property = "something else" //the new keyword changed 'this' to mean 'the object I'm about to return'
})();
DDaviesBrackett
+15  A: 
Triptych
So is it right to say that the "this" keyword allows for emulating dynamic scoping in javascript?. (In general all functions are said to have lexical/static scope)
techzen
+9  A: 

One possible alternative name would be owner. This would lead your mind in the direction that the owner can change depending on what code you are executing.

This example is from quirksmode:

In JavaScript this always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of. When we define our faithful function doSomething() in a page, its owner is the page, or rather, the window object (or global object) of JavaScript. An onclick property, though, is owned by the HTML element it belongs to.

In the following code,

function doSomething() {
   this.style.color = '#cc0000';
}

and

element.onclick = doSomething;

, owner points to the object that contains the method when it is executed.

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          --------------------                          |
|          | onclick property |                          |
|          --------------------                          |
|                                                        |
----------------------------------------------------------
Brian Ramsay
I didn't downvote (yet), but I don't like this answer, because it leads one to believe that the value of the this pointer is "always" determined by where the function is defined, which is completely untrue.
Triptych
A: 

I absorb novel syntax with little easy-to-type mental models such as:

$(document).ready(function() {

  function baffle() {
    alert(this.b);
  }

  function what() {
    this.b = "Hello";
    baffle();
  }

  function huh() {
    this.b = "World";
    baffle();
  }

  what();
  huh();

  }
);

This badly-translates into sloppy, imaginary C++ as:

template <class This>
function baffle() {
  alert(This.b);
}

function what() {
  b = "Hello";
  baffle<what>();
}

function huh() {
  b = "World";
  baffle<huh>();
}

what();
huh();
Thomas L Holaday
A: 

I think this is most appropriate for historical reasons. There isn't really a one-size-fits-all phrase for this in JavaScript, since not only can it be automatically assigned to very different references, e.g., this in the context of a procedural function or this in the context of an object, but this can also be assigned by the scripter using Function.apply and Function.call.

However, the meaning of this is only adjustable because JavaScript and the DOM work in some very weird ways. For example, the primary use of Function.apply is to preserve the context of an element reference in event calls. You will have seen this in Prototye's Function.bind() method.

this is a placeholder for the context in which the function is being executed, and it's hard to get any more specific than that. However, most uses of this make it a semantically appropriate keyword. In the case of bind(), even though we're using methods to arbitrarily change the meaning of this within the function, it should be used to make this more appropriate than it would be without. Many amateur JavaScript programmers are thrown off by the strange behavior of this in event handlers, and Function.apply is used to right that "wrong".

Andrew Noyes
A: 

Selfreferential logic (self or this) avoids paradoxes to advantage working on other than the self (this). Shall self (this) keep everything and all to one , it may as well stay static with no instance and with class method (static) instead. To avoid paradoxes, avoid selfreferences and logic keeps all truths provable and viceversa, all provables true.

LarsOn