2009-10-08 8 views
25

Ich versuche zu verstehen, warum in Javascript möchten Sie möglicherweise den Kontext einer Funktion ändern. Ich bin auf der Suche nach einem realen Beispiel oder etwas, das mir helfen wird, zu verstehen, wie/warum diese Technik verwendet wird und was ihre Bedeutung ist.Wie ändere ich den Kontext einer Funktion in Javascript

Die Technik dieses Beispiel veranschaulicht (Fa http://ejohn.org/apps/learn/#25) macht

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."); 
+13

Funny; Ich habe diese Seite gefunden, weil ich den Kontext für einen Anruf festlegen muss, den ich mache, und mich nicht an die Syntax erinnern konnte ... :) – rinogo

+1

+1 sollte betitelt werden: "Wie ändere ich den Kontext einer Funktion in Javascript" (jk - vielen Dank für die Veröffentlichung!) –

+0

+1 Ich war auf der Suche nach wie man das in einer Klasse konsistent halten ... – LoremIpsum

Antwort

20

jQuery Gebrauch zu guter Wirkung:

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

Der eigentliche Code jQuery wie folgt aussieht:

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

Wenn es nur callback(name, object[ name ]) danntatwürde nicht auf das aktuelle Objekt in Ihrem Iterator gesetzt und Sie müssten stattdessen den Parameter verwenden. Im Grunde macht es nur die Dinge einfacher.

+2

Nur um klar zu sein, der erste Parameter zu '.call()' wird 'this'. Weitere Details finden Sie unter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call – EpicVoyage

6

haben Sie einen Blick auf dieses Beispiel:

<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> 

Das neue Schlüsselwort ändert den Kontext.

3

Es ist sehr nützlich, wenn Rückrufe von AJAX-Anforderungen zu tun:

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); 
    }); 
}; 

Eigentlich, das ist ein ziemlich beschissenes Beispiel.

Es gibt Tonnen von Anwendungen in jQuery. Z. B. die jQuery() get() Funktion:

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

Es ist die Funktion des Array-Prototyp verwenden, aber im Rahmen des jQuery-Objekt.

3

Ein Beispiel aus der Praxis, die ich erlebt habe:

Wenn Sie eine Funktion als Event-Handler zu einem DOM-Elemente hinzufügen, und wenn Sie „das“ innerhalb dieser Funktion verwenden, „this“ auf das DOM beziehen Element, dem Sie den Ereignishandler hinzugefügt haben.

Aber diese Funktion könnte eine Methode eines Objekts sein und Sie möchten, dass das darin verwendete "this" -Schlüsselwort auf das Eigentümerobjekt verweist ... Sie müssen also den Kontext ändern, so dass "dies" nicht wird beziehen sich auf das DOM-Element, beziehen sich aber auf das Eigentümerobjekt.

Sie können den Kontext einer Funktion in jquery mit der Funktion proxy() einfach ändern. Sehen Sie diese Frage: jquery "this" binding issue on event handler (equivalent of bindAsEventListener in prototype) und die erste Antwort

0

ich mich immer in der Notwendigkeit, finden verschiedene Rahmen haben, wenn setTimeout mit und jQuery verfügt über eine praktische Funktion $.proxy, die der Trick:

function iAmCalledAfterTimeout() 
{ 
    alert(this.myProperty); //it will alert "hello world" 
}  

setTimeout($.proxy(iAmCalledAfterTimeout, {myProperty:"hello world"}), 1000); 
1

binden Funktion ist möglicherweise das, wonach Sie suchen, bind function gibt eine neue Funktion zurück in dem Kontext, den Sie übergeben haben, könnte ein reales Szenario sein, wenn Sie jquery Delegates verwenden, um ein Verhalten an ein dom Element anzuhängen, und Sie möchten Callback wird in einem anderen Kontext ausgeführt. weil der Standardkontext in einem jquery-delgate das dom-Objekt ist, das an den Handler gebunden ist, was bedeutet, dass Sie nicht auf eine Eigenschaft neben den Eigenschaften zugreifen können, die zum dom-Objekt gehören

Verwandte Themen