2009-01-19 23 views
124

Mam dość dobre zrozumienie JavaScript, z tym wyjątkiem, że nie mogę znaleźć ładny sposób, aby ustawić "tę" zmienną. Rozważ:Łatwo ustawić "tę" zmienną?

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body; //using body as example object 
someObj.foo_variable = "hi"; //set foo_variable so it alerts 

var old_fn = someObj.fn; //store old value 
someObj.fn = myFunction; //bind to someObj so "this" keyword works 
someObj.fn();    
someObj.fn = old_fn;  //restore old value 

Czy można to zrobić bez ostatnich 4 linii? To raczej irytujące ... Próbowałem wiążące anonimową funkcję, co uważałem, że był piękny i mądry, ale bezskutecznie:

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body;  //using body as example object 
someObj.foo_variable = "hi";  //set foo_variable so it alerts 
someObj.(function(){ fn(); })(); //fail. 

Oczywiście przechodzącą zmiennej do myFunction jest opcja ... ale to nie chodzi o to pytanie.

Dzięki.

Odpowiedz

207

Istnieją dwie metody zdefiniowane dla wszystkich funkcji Javascript, call() i apply(). Składnia funkcji wygląda następująco:

call(/* object */, /* arguments... */); 
apply(/* object */, /* arguments[] */); 

Co te funkcje zrobić, to wywołać funkcję oni powoływać na przypisanie wartości obiektu parametru ten.

var myFunction = function(){ 
    alert(this.foo_variable); 
} 
myFunction.call(document.body); 
+3

Ponadto, jeśli używasz jQuery, możesz użyć '$ .proxy (function, element)', aby kiedykolwiek ten functio n nazywa się, będzie w kontekście elementu. http://api.jquery.com/jquery.proxy/ –

54

myślę szukasz call:

myFunction.call(obj, arg1, arg2, ...); 

Wymaga myFunction z this zestaw do obj.

Istnieje również nieco inny sposób apply, która odbywa parametry funkcyjne w tablicy:

myFunction.apply(obj, [arg1, arg2, ...]); 
+1

Patrz rozdział 15.3.4.3, 15.3.4.4 i 10.1.8 specyfikacji języka ECMAScript w: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf – some

15

Jeśli chcesz „sklep” wartość this do funkcji, dzięki czemu można nazwać płynnie później (np gdy nie masz dostępu do tej wartości już), można go bind (niedostępne we wszystkich przeglądarkach chociaż):

var bound = func.bind(someThisValue); 

// ... later on, where someThisValue is not available anymore 

bound(); // will call with someThisValue as 'this' 
+5

FYI 'bind' jest podobno dostępny w IE9 +, FF4 +, Safari 5.1.4+ i Chrome 7+ [(źródło)] (http: //kangax.github. io/es5-compat-table/# Function.prototype.bind). Możesz także wywołać bind bezpośrednio na anonimowej funkcji: 'var myFunction = function() {/ * this = something * /} .bind (something);' – Adam

0

Moje poszukiwania w jaki sposób powiązać this przyprowadził mnie tutaj, więc jestem delegowania moje wyniki: w „ECMAScript 2015” możemy również ustawić ten leksykalnie za pomocą strzałek do funkcji.

Patrz: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Zamiast:

function Person() { 
    setInterval(function growUp() { 
    // The callback refers to the `self` variable of which 
    // the value is the expected object. 
    this.age++; 
    }.bind(this), 1000); 
} 

Możemy teraz zrobić:

function Person(){ 
    this.age = 0; 

    setInterval(() => { 
    this.age++; // |this| properly refers to the person object 
    }, 1000); 
} 

var p = new Person();