views:

379

answers:

3

I'm trying to understand why in javascript, you might want to change the context of a function. I'm looking for a real world example or something which will help me understand how / why this technique is used and what its significance is.

The technique is illustrated using this example (from http://ejohn.org/apps/learn/#25)

var object = {}; 
function fn(){ 
  return this; 
} 
assert( fn() == this, "The context is the global object." ); 
assert( fn.call(object) == object, "The context is changed to a specific object." );
+1  A: 

jQuery makes use of it to good effect:

$('a').each(function()
{
    // "this" is an a element - very useful
});

The actual jQuery code looks like this:

for ( name in object )
    if ( callback.call( object[ name ], name, object[ name ] ) === false )
        break;

If it just did callback( name, object[ name ] ) then this wouldn't be set to the current object in your iterator and you'd have to use the parameter instead. Basically it just makes things easier.

Greg
Thanks, but I'm struggling to see how this relates. Can you expand at all ?
neilc
aah!, that great. Thanks.
neilc
+2  A: 

Please have a look at this example:

<script>
var el = document.getElementById('button');
el.onclick = function(){
 this.value = "Press Me Again"; //this --> now refers to the the element button not on the window
}

//Another Example:
var Person = function(name,location){
  this.name = name;
  this.location = location;  
  alert(this.location); 
} 
var p2 = new Person("Samantha","California"); //this refers to the instance of the function Person(Person now acts as a class)
var p1 = Person(); // this refers to the window(Person simply acts as a simple function)
</script>
<button id="button1">Press Me</button>

The new keyword changes the context.

jerjer
+1  A: 

It's very useful when doing callbacks from AJAX requests:

function Person(_id, _name) {
    this.id = _id;
    this.name = _name;
};

Person.prototype.sayHi = function(greeting) {
    alert(greeting + " from " + this.name);
};

Person.prototype.loadFromAJAX = function(callback) {
    // in this example, it's jQuery, but could be anything
    var t = this;
    $.get("myurl.php", function(data) {
        callback.call(t, data.greeting);
    });
};

Actually, that's a pretty crappy example.

There are tons of uses of it in jQuery. For example, the jQuery().get() function:

get: function( num ) {
    return num === undefined ?
        // Return a 'clean' array
        Array.prototype.slice.call( this ) :
        // Return just the object
        this[ num ];
}

It's using the functions of the Array prototype but in the context of the jQuery object.

nickf