Jak zmienić kontekst funkcji w javascript

Próbuję zrozumieć, dlaczego w javascript możesz chcieć zmienić kontekst funkcji. Szukam przykładu z prawdziwego świata lub czegoś, co pomoże mi zrozumieć, jak / dlaczego ta technika jest używana i jakie jest jej znaczenie.

Technika jest zilustrowana na tym przykładzie (z 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." );
Author: Brian Tompsett - 汤莱恩, 2009-10-08

6 answers

JQuery używa go do dobrego efektu:

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

Rzeczywisty kod jQuery wygląda następująco:

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

Gdyby tak było callback( name, object[ name ] ) wtedy this nie zostałby ustawiony na bieżący obiekt w Twoim iteratorze i musiałbyś użyć tego parametru. To po prostu ułatwia sprawę.

 21
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-08 11:28:24

Proszę spojrzeć na ten przykład:

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

Nowe słowo kluczowe zmienia kontekst.

 6
Author: jerjer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-08 07:52:40

Jest to bardzo przydatne podczas wykonywania wywołań zwrotnych z żądań AJAX:

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);
    });
};
Właściwie to całkiem kiepski przykład.

Jest mnóstwo zastosowań jQuery. Na przykład jQuery ().funkcja get ():

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

Używa funkcji prototypu tablicy, ale w kontekście obiektu jQuery.

 3
Author: nickf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-08 08:10:06

Przykład z prawdziwego świata, z którym się spotkałem:

Jeśli dodasz funkcję jako obsługę zdarzeń do elementu DOM i jeśli użyjesz "this" wewnątrz tej funkcji, "this" będzie odnosić się do elementu DOM, do którego dodałeś obsługę zdarzeń.

Ale ta funkcja może być metodą obiektu i chcesz, aby słowo kluczowe "this" użyte wewnątrz niej odnosiło się do właściciela object...so musisz zmienić kontekst tak, aby "this" nie odnosił się do elementu DOM, ale odnosił się do obiekt właściciel .

Możesz łatwo zmienić kontekst funkcji w jquery za pomocą funkcji proxy (). Zobacz to pytanie: jquery " ten " problem związany z obsługą zdarzeń (odpowiednik bindAsEventListener w prototypie) i pierwsza odpowiedź

 3
Author: bogdan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:45:46

Funkcja Bind może być tym, czego szukasz, funkcja bind zwraca nową funkcję w kontekście, który przekazałeś , rzeczywisty scenariusz może być wtedy, gdy używasz delegatów jquery, aby dołączyć pewne zachowanie do elementu dom, i chcesz, aby wywołanie zwrotne zostało wykonane w innym kontekście. ponieważ domyślnym kontekstem w jQuery delgate jest obiekt dom, który jest powiązany z obsługą, co oznacza, że nie możesz uzyskać dostępu do żadnej właściwości poza właściwościami należącymi do dom obiekt

 1
Author: user2639874,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-31 21:53:01

Zawsze znajduję się w potrzebie posiadania innego kontekstu Podczas używania setTimeout i jQuery ma przydatną funkcję $.proxy co robi sztuczkę:

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

setTimeout($.proxy(iAmCalledAfterTimeout, {myProperty:"hello world"}), 1000);
 0
Author: algiecas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-28 09:39:58