2009-01-19 17 views
124

Tengo un conocimiento bastante bueno de Javascript, excepto que no puedo encontrar una buena manera de establecer la variable "this". Considere:Establecer "esta" variable fácilmente?

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 

¿Hay alguna manera de hacer esto sin las últimas 4 líneas? Es bastante molesto ... He intentado unir una función anónima, que me pareció hermosa e inteligente, pero fue en vano:

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. 

Obviamente, pasando la variable en myFunction es una opción ... pero eso es no es el punto de esta pregunta.

Gracias.

Respuesta

207

Hay dos métodos definidos para todas las funciones en JavaScript, call(), y apply(). La sintaxis de la función se parece a:

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

Lo que estas funciones hacen es llamar a la función que se invocaron en, asignando el valor del parámetro objeto de esta .

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

Además, si está utilizando jQuery, puede usar '$ .proxy (función, elemento)' para que siempre que esa funcion n se llama, será en el contexto de elemento. http://api.jquery.com/jquery.proxy/ –

54

creo que estás buscando call:

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

Para esto se necesitan myFunction con this conjunto de obj.

Existe también el método ligeramente diferente apply, que toma los parámetros de función como una matriz:

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

Véase la sección 15.3.4.3, 15.3.4.4 y 10.1.8 en la especificación del lenguaje ECMAScript: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf – some

15

Si desea 'tienda' el valor this a una función para que se le puede llamar más tarde sin problemas (por ejemplo, cuando usted no tiene acceso a ese valor ya no), puede bind (no disponible en todos los navegadores, aunque):

var bound = func.bind(someThisValue); 

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

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

FYI 'bind' aparentemente está disponible en IE9 +, FF4 +, Safari 5.1.4+ y Chrome 7+ [(fuente)] (http: //kangax.github. io/es5-compat-table/# Function.prototype.bind). También puede llamar a bind directamente en una función anónima: 'var myFunction = function() {/ * this = something * /} .bind (something);' – Adam

0

Mi búsqueda sobre cómo enlazar this me trajo aquí, así que estoy publicando mis hallazgos: en 'ECMAScript 2015' también podemos hacer esto usando léxico funciones de flecha a.

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

En lugar de:

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

Ahora podemos hacer:

function Person(){ 
    this.age = 0; 

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

var p = new Person(); 
Cuestiones relacionadas