Impostare facilmente questa "variabile"?


139

Ho una buona conoscenza di Javascript, tranne per il fatto che non riesco a capire un modo carino per impostare la variabile "this". Tener conto di:

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

C'è un modo per farlo senza le ultime 4 righe? È piuttosto fastidioso ... Ho provato a associare una funzione anonima, che pensavo fosse bella e intelligente, ma inutilmente:

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.

Ovviamente, passare la variabile in myFunction è un'opzione ... ma non è questo il punto di questa domanda.

Grazie.

Risposte:


221

Esistono due metodi definiti per tutte le funzioni in JavaScript call(), e apply(). La sintassi della funzione è simile a:

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

Quello che fanno queste funzioni è chiamare la funzione su cui sono state invocate, assegnando il valore del parametro oggetto a questo .

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

3
Inoltre, se stai usando jQuery, puoi usarlo in $.proxy(function, element)modo che ogni volta che viene chiamata quella funzione, sarà nel contesto dell'elemento. api.jquery.com/jquery.proxy
Trevin Avery,

Un altro metodo utile è.bind()
Soroush Falahati,

55

Penso che tu stia cercando call:

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

Questo chiama myFunctioncon thisset a obj.

C'è anche il metodo leggermente diverso apply, che prende i parametri della funzione come un array:

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

1
Vedi le sezioni 15.3.4.3, 15.3.4.4 e 10.1.8 in ECMAScript Specifiche del linguaggio: ecma-international.org/pilesations/files/ECMA-ST/Ecma-262.pdf
circa

18

Se vuoi "archiviare" il thisvalore in una funzione in modo da poterlo chiamare senza problemi in un secondo momento (ad esempio quando non hai più accesso a quel valore), puoi bindfarlo (non disponibile in tutti i browser):

var bound = func.bind(someThisValue);

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

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

7
FYI bindè apparentemente disponibile in IE9 +, FF4 +, Safari 5.1.4+ e Chrome 7+ (sorgente) . Puoi anche chiamare bind direttamente su una funzione anonima:var myFunction = function(){ /* this = something */ }.bind(something);
Adam

1

La mia ricerca su come legare thismi ha portato qui, quindi sto pubblicando i miei risultati: in 'ECMAScript 2015' possiamo anche impostare questo lessicamente usando le funzioni freccia su.

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

Invece di:

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

Ora possiamo fare:

function Person(){
  this.age = 0;

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

var p = new Person();

0

Impostazione della thisparola chiave in javascript.

Javascript ha 3 metodi integrati per impostare thiscomodamente la parola chiave. Si trovano tutti Function.prototypesull'oggetto in modo che ogni funzione possa utilizzarli (poiché ogni funzione eredita da questo prototipo tramite eredità prototipale). Queste funzioni sono le seguenti:

  1. Function.prototype.call(): Questa funzione accetta l'oggetto che si desidera utilizzare come thisprimo argomento. Quindi il resto degli argomenti sono i rispettivi argomenti della funzione che viene chiamata.
  2. Function.prototype.apply(): Questa funzione accetta l'oggetto che si desidera utilizzare come thisprimo argomento. Quindi il secondo argomento è un array che contiene i valori degli argomenti della funzione chiamata (il primo elemento dell'array è il primo argomento della funzione, il secondo argomento dell'array è il secondo argomento della funzione ecc.).
  3. Function.prototype.bind(): Questa funzione restituisce una nuova funzione che ha un valore diverso di this. Prende l'oggetto che si desidera impostare come thisvalore come primo argomento e quindi restituisce un nuovo oggetto funzione.

Differenza tra call / apply e bind:

  • calle applysono simili nel fatto che chiamano immediatamente la funzione (con un valore predefinito di this)
  • bindè diverso da calle applynel fatto che questa funzione restituisce una nuova funzione con un diverso legame del thisvalore.

Esempi:

const thisObj = {
  prop1: 1,
  prop2: 2,
};

function myFunc(arg1, arg2) {
  console.log(this.prop1, this.prop2);
  console.log(arg1, arg2);
}

// first arg this obj, other arguments are the  
// respective arguments of the function
myFunc.call(thisObj, 'Call_arg1', 'Call_arg2');

// first arg this obj, other argument is an array which  
// are the respective arguments of the function
myFunc.apply(thisObj, ['Apply_arg1', 'Apply_arg2']);


// the bind method returns a new function with a different
// this context which is stored in the newMyFunc variable
const newMyFunc = myFunc.bind(thisObj);

// now we can call the function like a normal function 
newMyFunc('first', 'second');

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.