-1

I am currently learning javascript at the moment and am struggling to understand objects, especially the "this" keyword. I have gone through tutorials on W3schools and searched youtube and would like if someone could provide a good tutorial on "this" in javascript.

jimkella
  • 11
  • 3
  • [https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Working_with_Objects#Using_this_for_object_references](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Working_with_Objects#Using_this_for_object_references) – lanzz Sep 20 '12 at 21:27
  • there's plenty already on here, except that the search engine seems to struggle to find the word "this" – Alnitak Sep 20 '12 at 21:28
  • Thanks for replies, will have to research a little more. – jimkella Sep 20 '12 at 21:34

2 Answers2

1

Ignoring Function.prototype.bind, introduced in ES5, the value of thisis set by how a function is called.

If a function is called with an unqualified identifier, e.g.

foo();

then on entering the function, this is undefined. In non-strict mode, it will be set to the global object (window in a browser) or in strict mode it will remain as undefined.

If a function is called as a method of an object, e.g.

someObj.foo();

then its this is set to the object.

If a function is called using the new operator, its this is set to a new Object created as if by new Object().

function Foo(name) {
    this.name = name; // this references a new Object
}

If a function is called using either call or apply, then its this can be set to any object in non–strict mode or to any value at all in strict mode (even null).

So this has nothing to do with execution context, scope, or anything else. It is entirely related to how a function is called or how the value is set using bind.

In regard to this in listeners, it's been answered here: onClick Function "this" Returns Window Object

Dynamically attached listeners are similar, but again there are quirks to deal with in older IE that are dealt with in articles on attaching listeners.

Community
  • 1
  • 1
RobG
  • 142,382
  • 31
  • 172
  • 209
0

this is kind of a tricky topic. this refers to the "owner" of the function you're currently working inside. Depending on what context, or scope it is in, this can mean several different things. Usually, it refers to the window object, which is in charge of keeping track of most of your javascript variables, as well as containing several functions. The reason for this is because unless they are explicitly defined otherwise, every javascript function's (and variable's) owner is window. In other words, the following is true:

<script type="text/javascript">
var something = "Hey";
this.something === something;    //these will evaluate to true, because when you  
window.something === something;  //declared the variable `something`, it was assigned  
this === window;                 //to the window object behind the scenes.
</script>

It doesn't always refer to window, though. Inside an event handler, this typically refers to the element that triggered the event. I don't want to go into event handlers in depth, but here's an example using jQuery. Side note -- learn the ins and outs of jQuery.

Html:

<div id="myDiv"></div>

Javascript:

<script type="text/javascript">
$('#myDiv').bind("click",function() {
                $(this).css("visibility","hidden");   
           });
</script>

In this example, this refers to the html element in the top box. The $() is around it because that is the syntax for creating a jQuery object for the element. I did this so I would be able to use the css function, but I could have just as easily done something like this.style.visibility = "hidden";

The reason this referred to the element in the above example is because behind the scenes, jQuery's bind method is doing something like this:

var ele = document.getElementById("myDiv");
ele.onclick = function(){ //the same function as above, but with all the  
                          //behind-the scenes stuff that jquery does to create a jQuery  
                          //object
                        };

Notice that because we're assigning the function to ele.onclick, the function "belongs" to the element, ele. Thus, inside that function, this should refer to ele.

If there is anything I left out that you still don't quite understand, let me know.

Phillip Schmidt
  • 8,805
  • 3
  • 43
  • 67
  • `this` has nothing to do with (execution) context or scope or "owner" objects, its value is set by how a function is called or [bind](http://ecma-international.org/ecma-262/5.1/#sec-15.3.4.5). – RobG Sep 20 '12 at 23:12
  • @RobG It has a lot to do with "owner" objects, actually. You just read too much into it. I was putting it into terms the OP could understand. *How a function is called* and *ownership* are the same thing in this context. If a function is a member of another object, that is, the other object *owns* it, `this` will refer to the *owner* object, provided that the function gets called normally from the object. Since most of that happens behind the scenes most of the time (with event listeners and such), I explained it in terms of "ownership", rather than in terms of how it is called. – Phillip Schmidt Sep 21 '12 at 14:11
  • @RobG Execution context, by the way, is directly related to "how a function is called". If we have a function foo(), and we set `someObject.onclick = foo;`, we now have two ways to call foo. If we call foo with just `foo()`, it executes in the window's scope, and `foo`'s owner is `window`. If we call `someObject.click()` or otherwise invoke the click handler, `foo` *executes* within the *scope* of the object. So, actually, if you don't take things overly literally, `this` has to do with execution context, scope, AND "owner" objects. You're just playing semantics. – Phillip Schmidt Sep 21 '12 at 14:16
  • @RobG Sorry to blow up the comments, but the last thing I'd like to add is that while you're correct, how you call a function decides what `this` is, the way you call a function isn't the root cause. The way you call a function **decides** its execution context/scope/parent, which decides what `this` refers to. – Phillip Schmidt Sep 21 '12 at 14:30
  • The only terms worth putting it into are those that align with ECMA-262. A function's `this` is dynamic and set entirely independently of its scope, which is more or less static (other than the use of `with`) based on how the function is declared or initialised. – RobG Sep 21 '12 at 15:46
  • @RobG A function's scope is static? K, let's take the above example I already used, then. We have a function `foo()`. It looks like this: `function foo(){alert(this);}`. Now we have `myObject.onclick = foo;` Now is foo's scope static? Doesn't appear so to me. Now let's say I click on `myObject`. Why, in this case, does this===myObject? Is it because of the way we called it? Yeah, kinda, but is that the *reason* that `this` equals the object? Not really. The *reason* is because the `foo()` that we called by clicking on `myObject` is a member of `myObject`. – Phillip Schmidt Sep 21 '12 at 16:02
  • @RobG just like if we were to call `foo` by just doing `foo()`, the *reason* `this` would equal `window` is because in that context, `foo()` is a member of `window`. Not because "we called it without a word and a little dot in front of it". The two are related, sure, but if you're looking for the direct reason for `this`'s value, it's because of its function's parent. – Phillip Schmidt Sep 21 '12 at 16:16
  • —you are defeating your own argument. `this` is set entirely by the call, it has **nothing** to do with scope, as you just proved. The scope of *foo* didn't change, its `this` did because of how the handler called the listener. The reason a function called in the global context has its `this` set to window is because on entering the function `this` is undefined, so it defaults to window. Read ECMA-262 §[10.4.1.1](http://ecma-international.org/ecma-262/5.1/#sec-10.4.1.1). Try it in strict mode, `this` will be undefined. Scope and `this` are completely different things. – RobG Sep 23 '12 at 23:31
  • Please read [Identifier Resolution, Execution Contexts and scope chains](http://jibbering.com/faq/notes/closures/#clIRExSc) by Richard Cornford. It was written before ES5 so it uses ed 3 language, but the concepts are identical. It's primarily about closures but it explains how a lexical environment is created when a function is entered. It's long, and should be read in conjunction with the spec, but it is also technically accurate. – RobG Sep 23 '12 at 23:34
  • As a final example, declare a global function. Now try to get access to any identifier on its scope chain other than those declared in its own scope or global variables. You can't (per the specification). Global variables are made properties of the global object for convenience. It's the only variable environment to do this, you can't directly access any other. – RobG Sep 23 '12 at 23:37