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." );
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.
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.
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.
A real world example that i've encountered:
If you add a function as an event handler to a DOM element and if you use "this" inside that function, "this" will refer to the DOM element that you added the event handler to.
But that function might be a method of an object and you want the "this" keyword used inside it to refer to the owner object...so you need to change the context so that " this " will not refer to the DOM element but will refer to the owner object .
You can easily change the context of a function in jquery using the proxy() function. See this question: jquery "this" binding issue on event handler (equivalent of bindAsEventListener in prototype) and the first answer
bind function might be what you're looking for, bind function returns a new function with in the context that you passed in , a real world scenario could be when you are using jquery delegates to attach some behavior to a dom element, and you want the callback being execute in a different context. 'cause the default context in a jquery delgate is the dom object that is bound to the handler , which means you can't access any property besides the properties that belongs to the dom object
I always find myself in the need of having different context when using setTimeout
and jQuery has a handy function $.proxy which does the trick:
function iAmCalledAfterTimeout()
{
alert(this.myProperty); //it will alert "hello world"
}
setTimeout($.proxy(iAmCalledAfterTimeout, {myProperty:"hello world"}), 1000);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.