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

794

Ich weiß das schon applyund callsind ähnliche Funktionen, die setzen this(Kontext einer Funktion).

Der Unterschied liegt in der Art und Weise, wie wir die Argumente senden (manuell gegen Array).

Frage:

Aber wann sollte ich die bind()Methode anwenden?

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

Royi Namir
quelle
9
Es ist nicht deine Schuld, wenn es Benutzer gibt, die sich die Reputationspunkte des OP ansehen, bevor sie eine Antwort veröffentlichen oder abstimmen :)
Gabriel Llamas
54
call and apply Rufe eine Funktion auf, während bind eine Funktion erstellt. Übergebencall()Sie jedoch Argumente einzeln undapply()als Argumentarray. Weitere Informationen finden Sie in der verknüpften Dokumentation, die Ihre Frage vollständig beantworten sollte.
Nein,
3
kind of weird there is not an existing question about this :In Bezug auf das. Dies liegt wahrscheinlich daran, dass bind()die beiden anderen bereits in JavaScript 1.8.5 - ECMA-262, 5. Ausgabe, vorhanden waren. Während call()und apply()gibt es seit JavaScript 1.3 - ECMA-262 3rd Edition. SO hat Fragen über sie wie: Was-ist-der-Differenz-zwischen-Call-and-Anwendung . Ich rate nur, als ich mich das selbst fragte.
Nein,
Benötigen Sie diese Methoden (aufrufen, anwenden, binden) hier? ohne dies können Sie auch die Methode aufrufen und dies wird nur auf Objekt verweisen
Mahi
checkout the link - techyaura-blogs.blogspot.com/2020/05/…
techyaura

Antworten:

131

Ich habe diesen Vergleich zwischen Funktionsobjekten, Funktionsaufrufen call/applyund vor bindeiniger Zeit erstellt:

Geben Sie hier die Bildbeschreibung ein

.bindMit dieser Option können Sie den thisWert jetzt festlegen und die Funktion in Zukunft ausführen , da ein neues Funktionsobjekt zurückgegeben wird.

Felix Kling
quelle
779

Verwenden .bind()Sie diese Option, wenn diese Funktion später in einem bestimmten Kontext aufgerufen werden soll, der bei Ereignissen hilfreich ist. Verwenden Sie .call()oder, .apply()wenn Sie die Funktion sofort aufrufen und den Kontext ändern möchten.

Call / Apply ruft die Funktion sofort auf, während bindeine Funktion zurückgegeben wird, bei deren späterer Ausführung der richtige Kontext für den Aufruf der ursprünglichen Funktion festgelegt wird. Auf diese Weise können Sie den Kontext in asynchronen Rückrufen und Ereignissen beibehalten.

Ich mache das oft:

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

Ich verwende es ausgiebig in Node.js für asynchrone Rückrufe, für die ich eine Mitgliedsmethode übergeben möchte, möchte aber dennoch, dass der Kontext die Instanz ist, die die asynchrone Aktion gestartet hat.

Eine einfache, naive Implementierung von bind wäre wie folgt:

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

Es steckt mehr dahinter (wie das Übergeben anderer Argumente), aber Sie können mehr darüber lesen und die tatsächliche Implementierung auf dem MDN sehen .

Hoffe das hilft.

Tschad
quelle
2
@RoyiNamir das ist richtig, Sie können die zurückgegebene "gebundene" Funktion später verwenden, und der Kontext wird beibehalten.
Chad
5
Genau das bindkehrt zurück.
Chad
@ RoyiNamir Meine Antwort bearbeitet
Chad
4
Sie können bind auch für Partials verwenden und Argumente übergeben, bevor die Funktion aufgerufen wird.
Andrew Kirkegaard
1
Sie implementieren nur die Bindung neu, es gibt keinen wirklichen Unterschied. In beiden Fällen wird es nur in einen Abschluss eingeschlossen, der Zugriff auf eine Bereichsvariable hat, die den Kontext enthält. Ihr Code ist im Grunde die Polyfüllung, die ich gepostet habe.
Tschad
446

Sie alle fügen dies der Funktion (oder dem Objekt) hinzu, und der Unterschied besteht im Funktionsaufruf (siehe unten).

call fügt dies in die Funktion ein und führt die Funktion sofort aus:

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"

bind fügt dies in die Funktion ein und muss separat wie folgt aufgerufen werden:

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"

oder so:

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

apply ähnelt dem Aufruf, mit der Ausnahme, dass ein Array-ähnliches Objekt verwendet wird, anstatt die Argumente einzeln aufzulisten:

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"                                     
Neugieriger Superheld
quelle
1
Bedeutet dies, dass der Unterschied darin besteht, dass Binden ein Abschluss ist?
Gregory R.
Sie haben mich gerade über die Argumentfunktion unterrichtet, die in einer Funktion über Ihr Code-Snippet verwendet wird. Es ist ratsam zu erwähnen "use strict", um zu vermeiden, dass solche reservierten Schlüsselwörter überschrieben werden. +1.
RBT
@ Max stimmte zu; Ich habe eine Bearbeitung eingereicht, in der "dies" falsch ist oder keinen Sinn ergibt, bis wir bind / call / apply verwenden
iono
1
Danke für die Verbesserungsvorschläge. Ich habe meine Antwort etwas bearbeitet. @iono Dein Vorschlag hatte einige Ungenauigkeiten, konnte ihn also nicht genehmigen, hat aber meine eigenen Änderungen in der Antwort vorgenommen. Hoffentlich ist es jetzt umfassender.
CuriousSuperhero
200

Antworte in EINFACHER Form

  • Call ruft die Funktion auf und ermöglicht es Ihnen, Argumente einzeln zu übergeben.
  • Apply ruft die Funktion auf und ermöglicht es Ihnen, Argumente als Array zu übergeben.
  • Bind gibt eine neue Funktion zurück, mit der Sie dieses Array und eine beliebige Anzahl von Argumenten übergeben können.

Beispiele für Anwenden vs. Anrufen vs. Binden

Anruf

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

Anwenden

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

Binden

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

Wann jeweils zu verwenden

Anruf und Bewerbung sind ziemlich austauschbar. Entscheiden Sie einfach, ob es einfacher ist, ein Array oder eine durch Kommas getrennte Liste von Argumenten einzusenden.

Ich erinnere mich immer daran, welches welches ist, indem ich mich daran erinnere, dass Call für Komma (getrennte Liste) und Apply für Array steht.

Binden ist ein bisschen anders. Es gibt eine neue Funktion zurück. Call and Apply führt die aktuelle Funktion sofort aus.

Binden ist für viele Dinge großartig. Wir können es verwenden, um Funktionen wie im obigen Beispiel zu curry. Wir können eine einfache Hallo-Funktion übernehmen und daraus ein Hallo-Hallo oder Hallo-Kelly machen. Wir können es auch für Ereignisse wie onClick verwenden, bei denen wir nicht wissen, wann sie ausgelöst werden, aber wir wissen, welchen Kontext sie haben sollen.

Referenz: codeplanet.io

Amit Shah
quelle
8
Tolle Antwort, wenn es mein Fragenbeitrag war, gebe ich DIR ein Häkchen.
AmerllicA
In callund apply, folgt daraus, dass Sie thisdas erste Argument als zuweisen würden , wenn Sie kein innerhalb der Methode haben null?
Daryll Santos
1
@DaryllSantos, laut MDN: thisArg Optional. Der Wert, der für den Aufruf einer Funktion angegeben wurde. Beachten Sie, dass dies möglicherweise nicht der tatsächliche Wert ist, den die Methode sieht: Wenn die Methode eine Funktion im nicht strengen Modus ist, werden null und undefiniert durch das globale Objekt ersetzt und primitive Werte in Objekte konvertiert. Wenn Sie dies also nicht in der Funktion verwenden, spielt es keine Rolle.
Amit Shah
4
call = = Komma, apply == Array war ein netter kleiner Trick zum Auswendiglernen
drlff
var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanFunktioniert einwandfrei und gibt VM128: 4 aus Hallo Hallo
Kup
53

Hiermit können Sie den Wert thisunabhängig davon festlegen, wie die Funktion aufgerufen wird. Dies ist sehr nützlich, wenn Sie mit Rückrufen arbeiten:

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

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

Das gleiche Ergebnis mit zu erzielen, callwürde folgendermaßen aussehen:

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

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
jantimon
quelle
5
Die Verwendung von .bind()wie zuvor gezeigt ist falsch. Wenn Sie eine fn.bind(obj)andere Funktion verwenden, wird diese zurückgegeben (nicht die, die Sie zuvor erstellt haben). Und es gibt keine Fähigkeit, den Wert des thisInneren der bindedFunktion zu ändern . Meist wird dies für Rückrufversicherungen verwendet this. Aber in Ihrem Beispiel gibt es keine Unterschiede im Ergebnis. Aber fn !== fn.bind(obj);Beachten Sie, dass.
ValeriiVasin
@InviS Ich verstehe deinen Kommentar nicht - warum gibt es keinen Unterschied?
Jantimon
2
Der Unterschied zwischen Anruf und Anwendung ist. Beim Aufruf übergeben Sie Argumente als durch Kommas getrennte Zeichenfolgen, während Sie beim Anwenden Argumente in Form eines Arrays übergeben können. Ruhe die sind gleich.
Ashish Yadav
durch Kommas getrennte Zeichenfolgen ? Übergeben Sie Argumente einfach als Komma getrennt !!
Sudhansu Choudhary
46

Angenommen, wir haben multiplicationFunktion

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

Erstellen wir einige Standardfunktionen mit bind

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

Jetzt ist multiby2 (b) gleich Multiplikation (2, b);

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

Was ist, wenn ich beide Parameter in bind übergebe?

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

Jetzt ist getSixAlways () gleich Multiplikation (3,2);

getSixAlways();//6

gerade übergebender Parameter gibt 6 zurück; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Dadurch wird eine neue Multiplikationsfunktion erstellt und der magicMultiplication zugewiesen.

Oh nein, wir verstecken die Multiplikationsfunktionalität in magicMultiplication.

Aufruf magicMultiplicationgibt ein Leerzeichen zurückfunction b()

bei der Ausführung funktioniert es gut magicMultiplication(6,5); //30

Wie wäre es mit einem Anruf und einer Bewerbung?

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

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

Mit einfachen Worten, binderstellt die Funktion callund applyführt die Funktion aus, während applydie Parameter im Array erwartet werden

tk120404
quelle
Sehr gut erklärt!
CatalinBerta
3
+1 für "In einfachen Worten, binderstellt die Funktion callund applyführt die Funktion aus, während applydie Parameter im Array erwartet werden"
Josh Buchea
32

Beide Function.prototype.call()und Function.prototype.apply()rufen eine Funktion mit einem bestimmten thisWert auf und geben den Rückgabewert dieser Funktion zurück.

Function.prototype.bind()Auf der anderen Seite wird eine neue Funktion mit einem bestimmten thisWert erstellt und diese Funktion zurückgegeben, ohne sie auszuführen.

Nehmen wir also eine Funktion, die so aussieht:

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

Nehmen wir nun ein Objekt, das so aussieht:

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

Wir können unsere Funktion folgendermaßen an unser Objekt binden:

Obj.log = logProp.bind(Obj);

Jetzt können wir Obj.logüberall in unserem Code ausführen:

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

Was wirklich interessant wird, ist, wenn Sie nicht nur einen Wert für this, sondern auch für sein Argument binden prop:

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

Wir können dies jetzt tun:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
John Slegers
quelle
23

bind : Es bindet die Funktion mit dem angegebenen Wert und Kontext, führt die Funktion jedoch nicht aus. Um die Funktion auszuführen, müssen Sie die Funktion aufrufen.

call : Führt die Funktion mit dem angegebenen Kontext und Parameter aus.

apply : Führt die Funktion mit dem angegebenen Kontext und Parameter als Array aus .

Siddhartha
quelle
einfach und bescheiden!
Habeeb Perwad
18

Hier ist ein guter Artikel , den Unterschied zwischen zu veranschaulichen bind(), apply()und call()fasst es als unten.

  • bind()ermöglicht es uns , auf die spezifische Aufgabe wird es sein, gebunden leicht einstellen dies , wenn eine Funktion oder Methode aufgerufen wird.

    // 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() Erlauben Sie uns, Methoden auszuleihen

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

    Ein Problem bei diesem Beispiel besteht darin, dass wir showDatadem carsObjekt eine neue Methode hinzufügen und dies möglicherweise nicht nur zum Ausleihen einer Methode tun möchten, da das Auto-Objekt möglicherweise bereits einen Eigenschafts- oder Methodennamen hat showData. Wir wollen es nicht versehentlich überschreiben. Wie wir in unserer Diskussion von Applyund Callunten sehen werden, ist es am besten, eine Methode entweder mit der Methode Applyoder auszuleihen Call.

  • bind() Erlauben Sie uns, eine Funktion zu curry

    Function Currying , auch als Teilfunktionsanwendung bezeichnet , ist die Verwendung einer Funktion (die ein oder mehrere Argumente akzeptiert), die eine neue Funktion mit einigen der bereits festgelegten Argumente zurückgibt.

    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 + ".";
        }
     }

    Wir können bind()diese greetFunktion verwenden, um sie zu curry

    // 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()oder call()um diesen Wert einzustellen

    Das apply, callundbind Methoden werden verwendet , die diesen Wert einzustellen , wenn eine Methode aufgerufen, und sie tun es auf leicht unterschiedliche Weise Gebrauch direkte Kontrolle und Flexibilität in unserem JavaScript - Code zu ermöglichen.

    Die Methoden applyund callsind beim Festlegen dieses Werts nahezu identisch, außer dass Sie die Funktionsparameter apply ()als Array übergeben , während Sie die Parameter einzeln auflisten müssen, um sie an die call ()Methode zu übergeben.

    Hier ist ein Beispiel, um dies in der Rückruffunktion zu verwenden calloder applyeinzustellen .

    // 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
  • Funktionen mit applyoder ausleihencall

    • Array-Methoden ausleihen

      Lassen Sie uns ein array-likeObjekt erstellen und einige Array-Methoden ausleihen, um unser Array-ähnliches Objekt zu bearbeiten.

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

      Ein weiterer häufiger Fall ist die folgende Konvertierung argumentsin ein Array

        // 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"]
    • Andere Methoden ausleihen

      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​
  • Verwenden Sie apply()diese Option, um eine Funktion mit variabler Arität auszuführen

Das Math.maxist ein Beispiel mit variabler arity Funktion,

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

Aber was ist, wenn wir eine Reihe von Zahlen haben, an die wir übergeben können Math.max? Wir können das nicht machen:

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

Hier apply ()hilft uns die Methode, verschiedene Funktionen auszuführen . Anstelle des oben genannten müssen wir das Zahlenfeld mit apply () wie folgt übergeben:

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
zangw
quelle
8

call / apply führt die Funktion sofort aus:

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

bind führt die Funktion nicht sofort aus, sondern gibt die verpackte Apply- Funktion zurück (für die spätere Ausführung):

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}
Eldiyar Talantbek
quelle
7

Syntax

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

Hier

  • thisArg ist das Objekt
  • argArray ist ein Array-Objekt
  • arg1, arg2, arg3, ... sind zusätzliche Argumente

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

Shiljo Paulson
quelle
6

Der grundlegende Unterschied zwischen Aufrufen, Übernehmen und Binden ist:

Bind wird verwendet, wenn Ihr Ausführungskontext später im Bild angezeigt werden soll.

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

Angenommen, ich möchte diese Methode in einer anderen Variablen verwenden

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

Um die Referenz des Autos in einer anderen Variablen zu verwenden, sollten Sie verwenden

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

Lassen Sie uns über eine umfassendere Verwendung der Bindefunktion sprechen

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

func();
// Number: 1

Warum? Da func jetzt mit Nummer 1 gebunden ist, zeigt es auf Global Object, wenn wir in diesem Fall keine Bindung verwenden.

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

func();
// Object

Call, Apply werden verwendet, wenn Sie die Anweisung gleichzeitig ausführen möchten.

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
Nishant Parashar
quelle
4

Anruf anwenden und binden. und wie unterschiedlich sie sind.

Lernen wir das Anrufen und Anwenden unter Verwendung einer beliebigen täglichen Terminologie.

Sie haben drei Autos, your_scooter , your_car and your_jetdie mit dem gleichen Mechanismus (Methode) beginnen. Wir haben ein Objekt automobilemit einer Methode erstellt 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");
    }
}

Lassen Sie uns verstehen, wann Anruf und Anwendung verwendet wird. Lets nehme an, dass Sie ein Ingenieur, und Sie haben your_scooter, your_carund your_jetdie mit einem push_button_engine_start nicht gekommen , und Sie wünschen , einen Dritten zu verwenden push_button_engineStart.

Wenn Sie die folgenden Codezeilen ausführen, wird ein Fehler ausgegeben. WARUM?

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

Das obige Beispiel gibt Ihrem_scooter, your_car, your_jet erfolgreich eine Funktion aus einem Automobilobjekt.

Lassen Sie uns tiefer eintauchen. Hier werden wir die obige Codezeile aufteilen. automobile.push_button_engineStarthilft uns, die angewandte Methode zu finden.

Weiterhin verwenden wir Apply oder Call mit der Punktnotation. automobile.push_button_engineStart.apply()

Wenden Sie nun zwei Parameter an und rufen Sie an.

  1. Kontext
  2. Argumente

Hier setzen wir den Kontext in die letzte Codezeile.

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

Der Unterschied zwischen call und apply besteht nur darin, dass apply Parameter in Form eines Arrays akzeptiert, während call einfach eine durch Kommas getrennte Liste von Argumenten akzeptieren kann.

Was ist die JS-Bindungsfunktion?

Eine Bindefunktion bindet im Grunde den Kontext von etwas und speichert es dann in einer Variablen zur späteren Ausführung.

Lassen Sie uns unser vorheriges Beispiel noch besser machen. Früher haben wir eine Methode verwendet, die zum Automobilobjekt gehört, und sie zur Ausrüstung verwendet your_car, your_jet and your_scooter. Stellen wir uns nun vor, wir möchten ein separates push_button_engineStartseparates System erstellen, um unsere Autos zu einem späteren Zeitpunkt der gewünschten Ausführung einzeln zu starten.

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

immer noch nicht zufrieden?

Lassen Sie es uns als Träne klar machen. Zeit zum Experimentieren. Wir werden zurückkehren, um die Funktionsanwendung aufzurufen und anzuwenden, und versuchen, den Wert der Funktion als Referenz zu speichern.

Das folgende Experiment schlägt fehl, da Aufruf und Anwenden sofort aufgerufen werden. Daher gelangen wir nie zum Stadium des Speicherns einer Referenz in einer Variablen, in der die Bindungsfunktion die Show stiehlt

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

Sagar Munjal
quelle
3

Aufruf: Aufruf ruft die Funktion auf und ermöglicht es Ihnen, Argumente einzeln zu übergeben

Anwenden: Anwenden ruft die Funktion auf und ermöglicht es Ihnen, Argumente als Array zu übergeben

Bind: Bind gibt eine neue Funktion zurück, mit der Sie dieses Array und eine beliebige Anzahl von Argumenten übergeben können.

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

Raju Poloju
quelle
2

call (): - Hier übergeben wir die Funktionsargumente einzeln, nicht in einem Array-Format

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 (): - Hier übergeben wir die Funktionsargumente in einem Array-Format

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

binden() :--

       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));
Raushan
quelle
2

JavaScript-Aufruf ()

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)

JavaScript anwenden ()

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

** Aufruf- und Apply-Funktion sind Differenzaufruf-Take-Separate-Argumente, aber Apply-Take-Array wie folgt: [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()
Shuvro
quelle
1

Stellen Sie sich vor, Binden ist nicht verfügbar. Sie können es einfach wie folgt konstruieren:

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

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

bindHelper(arguments);
Philippe Oceangermanique
quelle
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;
Pandhari
quelle
0

Das Hauptkonzept hinter all diesen Methoden ist das Funktionsgraben .

Durch das Ausleihen von Funktionen können wir die Methoden eines Objekts für ein anderes Objekt verwenden, ohne eine Kopie dieser Methode erstellen und an zwei verschiedenen Stellen verwalten zu müssen. Es wird durch die Verwendung von erreicht. Anruf() , . apply () oder. bind (), die alle vorhanden sind, um dies explizit für die von uns ausgeliehene Methode festzulegen

  1. Call ruft die Funktion sofort auf und ermöglicht es Ihnen, Argumente einzeln zu übergeben
  2. Apply ruft die Funktion sofort auf und ermöglicht die Übergabe von Argumenten als Array .
  3. Bind gibt eine neue Funktion zurück, und Sie können sie jederzeit aufrufen / aufrufen, indem Sie eine Funktion aufrufen.

Unten finden Sie ein Beispiel für all diese Methoden

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

ANRUF

Das erste Argument, z. B. Name innerhalb der Aufrufmethode, ist immer ein Verweis auf (diese) Variable, und letzteres ist eine Funktionsvariable

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

ANWENDEN

Die Methode apply ist dieselbe wie die Aufrufmethode. Der einzige Unterschied besteht darin, dass die Funktionsargumente in der Array-Liste übergeben werden

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

BINDEN

Die Bindungsmethode ist dieselbe wie der Aufruf, außer dass die Bindung eine Funktion zurückgibt, die später durch Aufrufen verwendet werden kann (ruft sie nicht sofort auf).

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

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

printMyNAme () ist die Funktion, die die Funktion aufruft

Unten ist der Link für jsfiddle

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

Arham Chowdhury
quelle
-1

Ich denke, die gleichen Stellen von ihnen sind: Alle von ihnen können diesen Wert einer Funktion ändern. Die Unterschiede von ihnen sind: Die Bindungsfunktion gibt als Ergebnis eine neue Funktion zurück; Die Methoden call und apply führen die Funktion sofort aus, apply kann jedoch ein Array als Parameter akzeptieren und das Array getrennt analysieren. Außerdem kann die Bindungsfunktion Currying sein.

Xin Tao
quelle
-3

Die Bindungsfunktion sollte verwendet werden, wenn wir eine Funktion mit einem bestimmten Kontext zuweisen möchten, z.

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

Wenn wir im obigen Beispiel die Funktion demo.setValue () aufrufen und die Funktion this.getValue direkt übergeben, wird die Funktion demo.setValue nicht direkt aufgerufen, da dies in setTimeout auf das Fensterobjekt verweist, sodass wir den Kontext des Demoobjekts an this.getValue übergeben müssen Funktion mit bind. Dies bedeutet, dass wir die Funktion nur im Kontext des Demo-Objekts übergeben und nicht die Funktion tatsächlich aufrufen.

Ich hoffe, du verstehst .

Weitere Informationen finden Sie in der Javascript-Bindungsfunktion, die Sie im Detail kennen

user7339156
quelle