gyaani_guy
gyaani_guy

Reputation: 3209

'this' inside of anonymous closure functions

(function(value) {
    this.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = this.value;        // possibly undefined (Why?)
    });
})(2);

Can someone explain the value of 'this' in the above code please ?

My understanding:

this.value = value // Line 2 - here this refers to the global object elt.innerHTML = this.value; // line 4 - why is this 'possibly' undefined. Please explain.

Edit: btw I have thoroughly read the explanation for 'this' in this( How does the "this" keyword work? ) post ( from where I got the above code)

Upvotes: 2

Views: 126

Answers (3)

Mike Samuel
Mike Samuel

Reputation: 120486

The basic algo that a JS interpreter uses to determine this is as below.

  1. When a function is called via its special call and apply methods, then this is the first parameter to call or apply.
  2. When a function is called from a bound function created via its bind method, then this is the this-value parameter to bind.
  3. When a function is called as a method (obj.method(params)) then this is the object from which the method is fetched, obj in the example.
  4. When a function is called otherwise, then this is the global object in non-strict mode or null otherwise.

Since each uses the special methods in (1) to pass the container as this, this in the inner function should be the result of $('.some-elements'), an array of jquery wrapped DOM nodes.

Upvotes: 1

raina77ow
raina77ow

Reputation: 106375

Inside the function sent as callback to .each() method, this refers to the DOM element (for each one in this collection wrapped in jQuery object), not window:

More importantly, the callback is fired in the context of the current DOM element, so the keyword this refers to the element.

(BTW, that makes a bit redundant that elt arg; at least, it's a bit unclear why do you use both this and elt to refer to the same thing there).

Yet not all DOM Elements have value property defined: afair, it's set only for a subset of Elements: input, select, textarea, option etc. That's probably the reason why you get undefined as a result.

You can easily adjust this by using jQuery.proxy() method:

$('.some-elements').each($.proxy(function(elt){
    elt.innerHTML = this.value;
}, this));

Now the function sent into .each() uses the outer this as its context (obviously, it no longer points to DOM Element, as elt does).

Upvotes: 3

krillgar
krillgar

Reputation: 12805

In line 4, this.value is referring to the "each" instance of $('.some-elements'). Inside any function, it then refers to the object that the function is operating on. In the case of the anonymous function, it's the global scope.

Upvotes: 1

Related Questions