Javascript call () & apply () vs bind ()?


794

Lo so già applye callsono funzioni simili che impostano this(contesto di una funzione).

La differenza sta nel modo in cui inviamo gli argomenti (manuale vs array)

Domanda:

Ma quando dovrei usare il bind()metodo?

var obj = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));

jsbin


9
Non è colpa tua se ci sono utenti che osservano i punti reputazione dell'OP prima di pubblicare una risposta o effettuare l'upgrade :)
Gabriel Llamas

54
chiama e applica chiama una funzione mentre il bind crea una funzione. Sebbene concall()te passi argomenti singolarmente eapply()come un array di argomenti. Per maggiori dettagli, consulta la documentazione collegata che dovrebbe essere in grado di rispondere completamente alla tua domanda.
No,

3
kind of weird there is not an existing question about this :A riguardo. Questo probabilmente perché è bind()stato aggiunto dopo che gli altri due erano già presenti in JavaScript 1.8.5 - ECMA-262, 5a edizione. Mentre call()e apply()sono in circolazione da JavaScript 1.3 - ECMA-262 3rd Edition. SO ha domande su di loro come: qual è la differenza tra chiamare e applicare . Sto solo indovinando però mentre me lo chiedevo.
No,

hai bisogno di questi metodi (chiama, applica, associa) qui ?? senza questo puoi anche chiamare il metodo e questo punterà solo ad obiettare
Mahi,

Risposte:


131

Ho creato questo confronto tra oggetti funzione, chiamate funzione call/applye bindqualche tempo fa:

inserisci qui la descrizione dell'immagine

.bindconsente di impostare il thisvalore ora consentendo al contempo di eseguire la funzione in futuro , poiché restituisce un nuovo oggetto funzione.


779

Utilizzare .bind()quando si desidera che tale funzione venga successivamente richiamata con un determinato contesto, utile negli eventi. Utilizzare .call()o .apply()quando si desidera richiamare immediatamente la funzione e modificare il contesto.

Chiama / applica chiama la funzione immediatamente, mentre bindrestituisce una funzione che, quando eseguita in seguito, avrà il contesto corretto impostato per chiamare la funzione originale. In questo modo è possibile mantenere il contesto in callback ed eventi asincroni.

Lo faccio molto:

function MyObject(element) {
    this.elm = element;

    element.addEventListener('click', this.onClick.bind(this), false);
};

MyObject.prototype.onClick = function(e) {
     var t=this;  //do something with [t]...
    //without bind the context of this function wouldn't be a MyObject
    //instance as you would normally expect.
};

Lo uso ampiamente in Node.js per callback asincroni per i quali voglio passare un metodo membro, ma voglio comunque che il contesto sia l'istanza che ha avviato l'azione asincrona.

Un'implementazione semplice e ingenua di bind sarebbe come:

Function.prototype.bind = function(ctx) {
    var fn = this;
    return function() {
        fn.apply(ctx, arguments);
    };
};

C'è di più (come passare altri argomenti), ma puoi leggere di più e vedere la vera implementazione su MDN .

Spero che sia di aiuto.


2
@RoyiNamir che è corretto, è possibile utilizzare la funzione "associata" restituita in un secondo momento e il contesto verrà mantenuto.
Chad,

5
Questo è esattamente ciò che bindritorna.
Ciad

@RoyiNamir Modificato la mia risposta
Ciad

4
Puoi anche usare bind per i parziali, passando argomenti prima di chiamare la funzione.
Andrew Kirkegaard,

1
Stai solo reimplementando il legame, non c'è davvero differenza. In entrambi i casi lo si sta semplicemente avvolgendo in una chiusura che ha accesso a una variabile ambito che contiene il contesto. Il tuo codice è sostanzialmente il polyfill che ho pubblicato.
Chad,

446

Tutti attribuiscono questo in funzione (o oggetto) e la differenza è nella funzione invocazione (vedi sotto).

call collega questo in funzione ed esegue immediatamente la funzione:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"

legano attribuisce questo in funzione ed ha bisogno di essere invocato a parte in questo modo:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"

o in questo modo:

...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"

apply è simile a call, tranne per il fatto che accetta un oggetto simile a un array anziché elencare gli argomenti uno alla volta:

function personContainer() {
  var person = {  
     name: "James Smith",
     hello: function() {
       console.log(this.name + " says hello " + arguments[1]);
     }
  }
  person.hello.apply(person, arguments);
}
personContainer("world", "mars"); // output: "James Smith says hello mars", note: arguments[0] = "world" , arguments[1] = "mars"                                     

1
Questo significa che la differenza è che Bind è una chiusura?
Gregory R.,

Mi hai appena insegnato le funzioni degli argomenti utilizzate all'interno di una funzione tramite il tuo frammento di codice. Si consiglia di menzionare "use strict"per evitare di ignorare tali parole chiave riservate. +1.
RBT,

@Max concordato; Ho inviato una modifica in cui "this" è errata o non ha senso fino a quando non usiamo bind / call / apply
iono

1
Grazie per i suggerimenti di miglioramento. Ho modificato un po 'la mia risposta. @iono Il tuo suggerimento ha avuto alcune imprecisioni, quindi non ho potuto approvarlo, ma ha fatto le mie modifiche nella risposta. Spero che ora sia più completo.
CuriousSuperhero,

200

Risposta in forma PIÙ SEMPLICE

  • Call richiama la funzione e consente di passare gli argomenti uno alla volta.
  • Applica richiama la funzione e consente di passare argomenti in un array.
  • Bind restituisce una nuova funzione, che consente di passare a questo array e qualsiasi numero di argomenti.

Esempi di applicazione vs. chiamata vs. associazione

Chiamata

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.call(person1, 'Hello'); // Hello Jon Kuperman
say.call(person2, 'Hello'); // Hello Kelly King

Applicare

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.apply(person1, ['Hello']); // Hello Jon Kuperman
say.apply(person2, ['Hello']); // Hello Kelly King

legare

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say() {
    console.log('Hello ' + this.firstName + ' ' + this.lastName);
}

var sayHelloJon = say.bind(person1);
var sayHelloKelly = say.bind(person2);

sayHelloJon(); // Hello Jon Kuperman
sayHelloKelly(); // Hello Kelly King

Quando utilizzarli

Chiama e applica sono piuttosto intercambiabili. Decidi semplicemente se è più facile inviare un array o un elenco di argomenti separato da virgole.

Ricordo sempre quale è quale ricordando che Call è per virgola (elenco separato) e Apply è per array.

Il legame è un po 'diverso. Restituisce una nuova funzione. Chiama e applica esegue immediatamente la funzione corrente.

Il bind è ottimo per molte cose. Possiamo usarlo per curry funzioni come nell'esempio sopra. Possiamo prendere una semplice funzione ciao e trasformarla in ciaoJon o ciaoKelly. Possiamo anche usarlo per eventi come onClick dove non sappiamo quando verranno licenziati ma sappiamo quale contesto vogliamo che abbiano.

Riferimento: codeplanet.io


8
Risposta fantastica, se era il mio post di domanda, ti do il segno di spunta.
Amerllic,

In calle apply, ne consegue che se non si dispone di un thismetodo inside, allora si assegnerebbe il primo argomento come null?
Daryll Santos,

1
@DaryllSantos, Secondo MDN: thisArg Facoltativo. Il valore di questo fornito per la chiamata a una funzione. Si noti che questo potrebbe non essere il valore effettivo visto dal metodo: se il metodo è una funzione in modalità non rigorosa, null e indefinito verranno sostituiti con l'oggetto globale e i valori primitivi verranno convertiti in oggetti. Quindi se non lo usi nella funzione non ha importanza.
Amit Shah,

4
call = = virgola, apply == array era un piccolo trucco di memorizzazione
drlff

var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanFunziona perfettamente e produce VM128: 4 Ciao Jon Kuperman
Pratik,

53

Permette di impostare il valore thisindipendentemente da come viene chiamata la funzione. Questo è molto utile quando si lavora con callback:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(sayHello.bind(obj), 1000);

Per ottenere lo stesso risultato con callsarebbe simile a questo:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);

5
L'uso di .bind()come hai mostrato prima non è corretto. Quando si utilizza fn.bind(obj)un'altra funzione verrà restituita (non quella creata in precedenza). E non ci sono abilità per cambiare valore thisall'interno della bindedfunzione. Principalmente viene utilizzato per l' thisassicurazione di callback . Ma nel tuo esempio - non ci sono differenze nel risultato. Ma fn !== fn.bind(obj);notalo.
ValeriiVasin,

@InviS Non capisco il tuo commento - perché non c'è differenza?
jantimon,

2
La differenza tra chiamare e applicare è. in call passi argomenti come stringhe separate da virgola, mentre in apply puoi passare argomenti in forma di array. il resto è lo stesso.
Ashish Yadav,

stringhe separate da virgola ?? basta passare argomenti separati da virgola !!
Sudhansu Choudhary,

46

Supponiamo di avere una multiplicationfunzione

function multiplication(a,b){
console.log(a*b);
}

Consente di creare alcune funzioni standard utilizzando bind

var multiby2 = multiplication.bind(this,2);

Ora multiby2 (b) è uguale alla moltiplicazione (2, b);

multiby2(3); //6
multiby2(4); //8

Che cosa succede se passo entrambi i parametri in bind

var getSixAlways = multiplication.bind(this,3,2);

Ora getSixAlways () è uguale alla moltiplicazione (3,2);

getSixAlways();//6

passando anche il parametro restituisce 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Questo crea una nuova funzione di moltiplicazione e la assegna a magicMultiplication.

Oh no, stiamo nascondendo la funzionalità di moltiplicazione in magicMultiplication.

la chiamata magicMultiplicationrestituisce uno spaziofunction b()

su esecuzione funziona benissimo magicMultiplication(6,5); //30

Che ne dici di chiamare e fare domanda?

magicMultiplication.call(this,3,2); //6

magicMultiplication.apply(this,[5,2]); //10

In parole semplici, bindcrea la funzione called applyesegue la funzione mentre si applyaspetta i parametri nella matrice


Molto ben spiegato!
CatalinBerta,

3
+1 per "In parole semplici, bindcrea la funzione called applyesegue la funzione mentre si applyaspetta i parametri nell'array"
Josh Buchea

32

Entrambi Function.prototype.call()e Function.prototype.apply()chiamano una funzione con un dato thisvalore e restituiscono il valore restituito di quella funzione.

Function.prototype.bind(), d'altra parte, crea una nuova funzione con un dato thisvalore e restituisce quella funzione senza eseguirla.

Quindi, prendiamo una funzione simile a questa:

var logProp = function(prop) {
    console.log(this[prop]);
};

Ora prendiamo un oggetto simile al seguente:

var Obj = {
    x : 5,
    y : 10
};

Possiamo associare la nostra funzione al nostro oggetto in questo modo:

Obj.log = logProp.bind(Obj);

Ora, possiamo eseguire Obj.logovunque nel nostro codice:

Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10

Dove diventa davvero interessante, è quando non solo si associa un valore per this, ma anche per il suo argomento prop:

Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');

Ora possiamo fare questo:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10

23

bind : lega la funzione con il valore e il contesto forniti, ma non esegue la funzione. Per eseguire la funzione è necessario chiamare la funzione.

call : esegue la funzione con il contesto e il parametro forniti.

applica : Esegue la funzione con il contesto e il parametro forniti come array .


semplice e umile!
Habeeb Perwad,

18

Ecco un articolo buono per illustrare la differenza tra bind(), apply()e call(), riassumere come segue.

  • bind()ci consente di impostare facilmente quale oggetto specifico sarà associato a questo quando viene invocata una funzione o un metodo.

    // This data variable is a global variable​
    var data = [
        {name:"Samantha", age:12},
        {name:"Alexis", age:14}
    ]
    var user = {
        // local data variable​
        data    :[
            {name:"T. Woods", age:37},
            {name:"P. Mickelson", age:43}
        ],
        showData:function (event) {
            var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // random number between 0 and 1​
            console.log (this.data[randomNum].name + " " + this.data[randomNum].age);
        }
    }
    
    // Assign the showData method of the user object to a variable​
    var showDataVar = user.showData;
    showDataVar (); // Samantha 12 (from the global data array, not from the local data array)​
    /*
    This happens because showDataVar () is executed as a global function and use of this inside 
    showDataVar () is bound to the global scope, which is the window object in browsers.
    */
    
    // Bind the showData method to the user object​
    var showDataVar = user.showData.bind (user);
    // Now the we get the value from the user object because the this keyword is bound to the user object​
    showDataVar (); // P. Mickelson 43​
  • bind() ci permettono di prendere in prestito metodi

    // Here we have a cars object that does not have a method to print its data to the console​
    var cars = {
        data:[
           {name:"Honda Accord", age:14},
           {name:"Tesla Model S", age:2}
       ]
    }
    
    // We can borrow the showData () method from the user object we defined in the last example.​
    // Here we bind the user.showData method to the cars object we just created.​
    cars.showData = user.showData.bind (cars);
    cars.showData (); // Honda Accord 14​

    Un problema con questo esempio è che stiamo aggiungendo un nuovo metodo showDatain carsoggetto e che potremmo non vogliono fare questo solo per prendere in prestito un metodo perché l'oggetto auto potrebbe già avere un nome di proprietà o un metodo showData. Non vogliamo sovrascriverlo accidentalmente. Come vedremo nella nostra discussione di Applye Callsotto, è meglio prendere in prestito un metodo usando il metodo Applyo Call.

  • bind() ci permettono di curry una funzione

    La funzione Currying , nota anche come applicazione di funzione parziale , è l'uso di una funzione (che accetta uno o più argomenti) che restituisce una nuova funzione con alcuni degli argomenti già impostati.

    function greet (gender, age, name) {
        // if a male, use Mr., else use Ms.​
        var salutation = gender === "male" ? "Mr. " : "Ms. ";
        if (age > 25) {
            return "Hello, " + salutation + name + ".";
        }else {
            return "Hey, " + name + ".";
        }
     }

    Possiamo usare bind()per curry questa greetfunzione

    // So we are passing null because we are not using the "this" keyword in our greet function.
    var greetAnAdultMale = greet.bind (null, "male", 45);
    
    greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."
    
    var greetAYoungster = greet.bind (null, "", 16);
    greetAYoungster ("Alex"); // "Hey, Alex."​
    greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
  • apply()o call()per impostare questo valore

    I apply, calle bindmetodi sono tutti utilizzati per impostare il questo valore quando si fa una chiamata, e lo fanno in modi piuttosto differenti per permettere un controllo diretto uso e la versatilità nel nostro codice JavaScript.

    I metodi applye callsono quasi identici quando si imposta questo valore tranne per il fatto che si passano i parametri della funzione apply ()come array , mentre è necessario elencare i parametri singolarmente per passarli al call ()metodo.

    Ecco un esempio per utilizzare callo applyimpostare questo nella funzione di richiamata.

    // Define an object with some properties and a method​
    // We will later pass the method as a callback function to another function​
    var clientData = {
        id: 094545,
        fullName: "Not Set",
        // setUserName is a method on the clientData object​
        setUserName: function (firstName, lastName)  {
            // this refers to the fullName property in this object​
            this.fullName = firstName + " " + lastName;
        }
    };
    
    function getUserInput (firstName, lastName, callback, callbackObj) {
         // The use of the Apply method below will set the "this" value to callbackObj​
         callback.apply (callbackObj, [firstName, lastName]);
    }
    
    // The clientData object will be used by the Apply method to set the "this" value​
    getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
    // the fullName property on the clientData was correctly set​
    console.log (clientData.fullName); // Barack Obama
  • Prendere in prestito funzioni con applyocall

    • Metodi di matrice di prestito

      Creiamo un array-likeoggetto e prendiamo in prestito alcuni metodi di matrice per operare sul nostro oggetto simile a matrice.

      // An array-like object: note the non-negative integers used as keys​
      var anArrayLikeObj = {0:"Martin", 1:78, 2:67, 3:["Letta", "Marieta", "Pauline"], length:4 };
      
       // Make a quick copy and save the results in a real array:
       // First parameter sets the "this" value​
       var newArray = Array.prototype.slice.call (anArrayLikeObj, 0);
       console.log (newArray); // ["Martin", 78, 67, Array[3]]​
      
       // Search for "Martin" in the array-like object​
       console.log (Array.prototype.indexOf.call (anArrayLikeObj, "Martin") === -1 ? false : true); // true​

      Un altro caso comune è quello di convertire argumentsin array come segue

        // We do not define the function with any parameters, yet we can get all the arguments passed to it​
       function doSomething () {
          var args = Array.prototype.slice.call (arguments);
          console.log (args);
       }
      
       doSomething ("Water", "Salt", "Glue"); // ["Water", "Salt", "Glue"]
    • Prendi in prestito altri metodi

      var gameController = {
           scores  :[20, 34, 55, 46, 77],
           avgScore:null,
           players :[
                {name:"Tommy", playerID:987, age:23},
                {name:"Pau", playerID:87, age:33}
           ]
       }
       var appController = {
           scores  :[900, 845, 809, 950],
           avgScore:null,
           avg     :function () {
                   var sumOfScores = this.scores.reduce (function (prev, cur, index, array) {
                        return prev + cur;
               });
               this.avgScore = sumOfScores / this.scores.length;
           }
         }
         // Note that we are using the apply () method, so the 2nd argument has to be an array​
         appController.avg.apply (gameController);
         console.log (gameController.avgScore); // 46.4​
         // appController.avgScore is still null; it was not updated, only gameController.avgScore was updated​
         console.log (appController.avgScore); // null​
  • Utilizzare apply()per eseguire la funzione di arità variabile

Questo Math.maxè un esempio di funzione ad arità variabile,

// We can pass any number of arguments to the Math.max () method​
console.log (Math.max (23, 11, 34, 56)); // 56

E se avessimo una matrice di numeri a cui passare Math.max? Non possiamo farlo:

var allNumbers = [23, 11, 34, 56];
// We cannot pass an array of numbers to the the Math.max method like this​
console.log (Math.max (allNumbers)); // NaN

È qui che il apply ()metodo ci aiuta a eseguire funzioni variadiche . Invece di quanto sopra, dobbiamo passare la matrice di numeri usando apply () in questo modo:

var allNumbers = [23, 11, 34, 56];
// Using the apply () method, we can pass the array of numbers:
console.log (Math.max.apply (null, allNumbers)); // 56

8

call / apply esegue immediatamente la funzione:

func.call(context, arguments);
func.apply(context, [argument1,argument2,..]);

bind non esegue immediatamente la funzione, ma restituisce la funzione di applicazione wrapping (per un'esecuzione successiva):

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}

7

Sintassi

  • call (thisArg, arg1, arg2, ...)
  • applicare (thisArg, argsArray)
  • bind (thisArg [, arg1 [, arg2 [, ...]]])

Qui

  • thisArg è l'oggetto
  • argArray è un oggetto array
  • arg1, arg2, arg3, ... sono argomenti aggiuntivi

function printBye(message1, message2){
    console.log(message1 + " " + this.name + " "+ message2);
}

var par01 = { name:"John" };
var msgArray = ["Bye", "Never come again..."];

printBye.call(par01, "Bye", "Never come again...");
//Bye John Never come again...

printBye.call(par01, msgArray);
//Bye,Never come again... John undefined

//so call() doesn't work with array and better with comma seperated parameters 

//printBye.apply(par01, "Bye", "Never come again...");//Error

printBye.apply(par01, msgArray);
//Bye John Never come again...

var func1 = printBye.bind(par01, "Bye", "Never come again...");
func1();//Bye John Never come again...

var func2 = printBye.bind(par01, msgArray);
func2();//Bye,Never come again... John undefined
//so bind() doesn't work with array and better with comma seperated parameters


6

Le differenze di base tra Call, Apply e Bind sono:

Il bind verrà utilizzato se si desidera che il contesto di esecuzione venga visualizzato più avanti nella figura.

Ex:

var car = { 
  registrationNumber: "007",
  brand: "Mercedes",

  displayDetails: function(ownerName){
    console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
  }
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**

Diciamo che voglio usare questo metodo in qualche altra variabile

var car1 = car.displayDetails('Nishant');
car1(); // undefined

Per usare il riferimento dell'auto in qualche altra variabile dovresti usare

var car1 = car.displayDetails.bind(car, 'Nishant');
car1(); // Nishant this is your car 007 Mercedes

Parliamo di un uso più esteso della funzione bind

var func = function() {
 console.log(this)
}.bind(1);

func();
// Number: 1

Perché? Poiché ora func è associato a Numero 1, se in questo caso non utilizziamo il binding, punterà a Global Object.

var func = function() {
 console.log(this)
}.bind({});

func();
// Object

Chiama, Applica vengono utilizzati quando si desidera eseguire contemporaneamente l'istruzione.

var Name = { 
    work: "SSE",
    age: "25"
}

function displayDetails(ownerName) {
    console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE

In apply we pass the array
displayDetails.call(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE

4

Chiama applicare e associare. e come sono diversi.

Consente di imparare a chiamare e applicare utilizzando qualsiasi terminologia giornaliera.

Hai tre automobili your_scooter , your_car and your_jetche iniziano con lo stesso meccanismo (metodo). Abbiamo creato un oggetto automobilecon un metodo push_button_engineStart.

var your_scooter, your_car, your_jet;
var automobile = {
        push_button_engineStart: function (runtime){
        console.log(this.name + "'s" + ' engine_started, buckle up for the ride for ' + runtime + " minutes");
    }
}

Consente di capire quando è chiamata e applicare utilizzato. Supponiamo che tu sia un ingegnere e tu abbia your_scooter, your_care your_jetche non è venuto con un push_button_engine_start e che desideri utilizzare una terza parte push_button_engineStart.

Se si eseguono le seguenti righe di codice, verranno visualizzati degli errori. PERCHÉ?

//your_scooter.push_button_engineStart();
//your_car.push_button_engineStart();
//your_jet.push_button_engineStart();


automobile.push_button_engineStart.apply(your_scooter,[20]);
automobile.push_button_engineStart.call(your_jet,10);
automobile.push_button_engineStart.call(your_car,40);

Quindi l'esempio sopra riportato dà a your_scooter, your_car, your_jet una funzione dall'oggetto automobile.

Tuffiamoci più in profondità Qui divideremo la riga di codice sopra. automobile.push_button_engineStartci sta aiutando a ottenere il metodo utilizzato.

Inoltre usiamo apply o call usando la notazione punto. automobile.push_button_engineStart.apply()

Ora applica e chiama accetta due parametri.

  1. contesto
  2. argomenti

Quindi qui impostiamo il contesto nell'ultima riga di codice.

automobile.push_button_engineStart.apply(your_scooter,[20])

La differenza tra call e apply è solo che apply accetta i parametri sotto forma di un array mentre call può semplicemente accettare un elenco di argomenti separato da virgole.

che cos'è la funzione JS Bind?

Una funzione di bind è fondamentalmente che lega il contesto di qualcosa e quindi lo memorizza in una variabile per l'esecuzione in una fase successiva.

Facciamo ancora meglio il nostro esempio precedente. In precedenza abbiamo usato un metodo appartenente all'oggetto automobile e l'abbiamo usato per equipaggiare your_car, your_jet and your_scooter. Ora immaginiamo di voler dare un separato push_button_engineStartseparatamente per avviare le nostre automobili individualmente in qualsiasi fase successiva dell'esecuzione che desideriamo.

var scooty_engineStart = automobile.push_button_engineStart.bind(your_scooter);
var car_engineStart = automobile.push_button_engineStart.bind(your_car);
var jet_engineStart = automobile.push_button_engineStart.bind(your_jet);


setTimeout(scooty_engineStart,5000,30);
setTimeout(car_engineStart,10000,40);
setTimeout(jet_engineStart,15000,5);

non sei ancora soddisfatto?

Facciamo in modo chiaro come lacrima. È tempo di sperimentare. Torneremo a chiamare e ad applicare l'applicazione della funzione e proveremo a memorizzare il valore della funzione come riferimento.

L'esperimento riportato di seguito fallisce perché call e apply vengono invocati immediatamente, quindi non arriviamo mai alla fase di memorizzazione di un riferimento in una variabile in cui la funzione bind ruba lo spettacolo

var test_function = automobile.push_button_engineStart.apply(your_scooter);


3

Chiama: call richiama la funzione e consente di passare argomenti uno alla volta

Applica: Applica richiama la funzione e consente di passare argomenti come un array

Bind: Bind restituisce una nuova funzione, che consente di passare a questo array e qualsiasi numero di argomenti.

var person1 = {firstName: 'Raju', lastName: 'king'};
var person2 = {firstName: 'chandu', lastName: 'shekar'};

function greet(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
function greet2(greeting) {
        console.log( 'Hello ' + this.firstName + ' ' + this.lastName);
    }


greet.call(person1, 'Hello'); // Hello Raju king
greet.call(person2, 'Hello'); // Hello chandu shekar



greet.apply(person1, ['Hello']); // Hello Raju king
greet.apply(person2, ['Hello']); // Hello chandu shekar

var greetRaju = greet2.bind(person1);
var greetChandu = greet2.bind(person2);

greetRaju(); // Hello Raju king
greetChandu(); // Hello chandu shekar


2

call (): - Qui passiamo gli argomenti della funzione singolarmente, non in un formato array

var obj = {name: "Raushan"};

var greeting = function(a,b,c) {
    return "Welcome "+ this.name + " to "+ a + " " + b + " in " + c;
};

console.log(greeting.call(obj, "USA", "INDIA", "ASIA"));

apply (): - Qui passiamo gli argomenti della funzione in un formato array

var obj = {name: "Raushan"};

var cal = function(a,b,c) {
    return this.name +" you got " + a+b+c;
};

var arr =[1,2,3];  // array format for function arguments
console.log(cal.apply(obj, arr)); 

bind (): -

       var obj = {name: "Raushan"};

       var cal = function(a,b,c) {
            return this.name +" you got " + a+b+c;
       };

       var calc = cal.bind(obj);
       console.log(calc(2,3,4));

2

Chiamata JavaScript ()

const person = {
    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.call(anotherPerson,1,2)

Applica JavaScript ()

    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.apply(anotherPerson,[1,2])

** la funzione call and apply è differenza chiama take argomento separato ma applica take array come: [1,2,3] **

JavaScript bind ()

    name: "Lokamn",
    dob: 12,
    anotherPerson: {
        name: "Pappu",
        dob: 12,
        print2: function () {
            console.log(this)
        }
    }
}

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()

1

Immagina, il bind non è disponibile. puoi facilmente costruirlo come segue:

var someFunction=...
var objToBind=....

var bindHelper =  function (someFunction, objToBind) {
    return function() {
        someFunction.apply( objToBind, arguments );
    };  
}

bindHelper(arguments);

1
    function sayHello() {
            //alert(this.message);
            return this.message;
    }
    var obj = {
            message: "Hello"
    };

    function x(country) {
            var z = sayHello.bind(obj);
            setTimeout(y = function(w) {
//'this' reference not lost
                    return z() + ' ' + country + ' ' + w;
            }, 1000);
            return y;
    }
    var t = x('India')('World');
    document.getElementById("demo").innerHTML = t;

0

Il concetto principale alla base di tutti questi metodi è il burrowing delle funzioni .

Il prestito di funzioni ci consente di utilizzare i metodi di un oggetto su un oggetto diverso senza dover fare una copia di quel metodo e mantenerlo in due luoghi separati. È realizzato attraverso l'uso di. call (),. applicare () o. bind (), che esistono tutti per impostare esplicitamente questo sul metodo che stiamo prendendo in prestito

  1. Call richiama immediatamente la funzione e consente di passare gli argomenti uno alla volta
  2. Applica richiama immediatamente la funzione e consente di passare argomenti in un array .
  3. legare restituisce una nuova funzione e puoi invocarla / chiamarla in qualsiasi momento invocando una funzione.

Di seguito è riportato un esempio di tutti questi metodi

let name =  {
    firstname : "Arham",
    lastname : "Chowdhury",
}
printFullName =  function(hometown,company){
    console.log(this.firstname + " " + this.lastname +", " + hometown + ", " + company)
}

CHIAMATA

il primo argomento, ad esempio nome all'interno del metodo call, è sempre un riferimento a (questa) variabile e quest'ultima sarà variabile di funzione

printFullName.call(name,"Mumbai","Taufa");     //Arham Chowdhury, Mumbai, Taufa

APPLICARE

Il metodo apply è uguale al metodo call, l'unica differenza è che gli argomenti della funzione vengono passati nell'elenco Array

printFullName.apply(name, ["Mumbai","Taufa"]);     //Arham Chowdhury, Mumbai, Taufa

BIND

il metodo bind è uguale a call tranne quello, il bind restituisce una funzione che può essere utilizzata in seguito invocandola (non la chiama immediatamente)

let printMyNAme = printFullName.bind(name,"Mumbai","Taufa");

printMyNAme();      //Arham Chowdhury, Mumbai, Taufa

printMyNAme () è la funzione che invoca la funzione

di seguito è riportato il link per jsfiddle

https://codepen.io/Arham11/pen/vYNqExp


-1

Penso che gli stessi posti siano: tutti possono cambiare questo valore di una funzione. Le differenze sono: la funzione di associazione restituirà una nuova funzione di conseguenza; i metodi call e apply eseguiranno immediatamente la funzione, ma apply può accettare una matrice come parametri e analizzerà la matrice separata. Inoltre, la funzione di associazione può essere Currying.


-3

La funzione bind dovrebbe essere usata quando vogliamo assegnare una funzione con un contesto particolare per es.

var demo = {
           getValue : function(){ 
             console.log('demo object get value       function') 
            }
           setValue : function(){  
              setTimeout(this.getValue.bind(this),1000)           
           }
 }

nell'esempio precedente se chiamiamo la funzione demo.setValue () e passiamo direttamente la funzione this.getValue, allora non chiama direttamente la funzione demo.setValue perché questo in setTimeout si riferisce all'oggetto finestra, quindi dobbiamo passare il contesto dell'oggetto demo a this.getValue funzione usando bind. significa che stiamo solo passando la funzione con il contesto dell'oggetto demo che non chiama in modo effettivo la funzione.

Spero che tu capisca

per ulteriori informazioni, consultare la funzione di associazione javascript sapere in dettaglio

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.