1017 Stimmen

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

Ich weiß bereits, dass apply y call sind ähnliche Funktionen, die die this (Kontext einer Funktion).

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

Pregunta:

Aber wann sollte ich die bind() Verfahren ?

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

58voto

jantimon Punkte 34906

Sie ermöglicht die Einstellung des Wertes für this unabhängig davon, wie die Funktion aufgerufen wird. Dies ist sehr nützlich bei der Arbeit mit Rückrufen:

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

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

Um das gleiche Ergebnis zu erzielen mit call würde wie folgt aussehen:

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

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

52voto

Arham Chowdhury Punkte 522

Das Hauptkonzept hinter all diesen Methoden ist Funktion Wühlen .

Das Ausleihen von Funktionen ermöglicht es uns, die Methoden eines Objekts auf einem anderen Objekt zu verwenden, ohne eine Kopie dieser Methode zu erstellen und sie an zwei verschiedenen Stellen zu pflegen. Erreicht wird dies durch die Verwendung von . call() , . apply() oder . bind() , die alle dazu dienen, die Methode, die wir ausleihen, explizit festzulegen

  1. Rufen Sie an. ruft die Funktion sofort auf und erlaubt es Ihnen, die Argumente einzeln zu übergeben einzeln
  2. Bewerbung ruft die Funktion sofort auf und erlaubt es Ihnen, Argumente zu übergeben als Array .
  3. Binden Sie gibt eine neue Funktion zurück, die Sie jederzeit aufrufen können, indem Sie eine Funktion aufrufen.

Im Folgenden finden Sie ein Beispiel für alle diese Methoden

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

ANRUFEN

das erste Argument, z.B. Name innerhalb der Aufrufmethode, ist immer ein Verweis auf (diese) Variable und letztere wird zur Funktionsvariablen

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

APPLY

a der einzige Unterschied ist, dass die Funktionsargumente in einer Array-Liste übergeben werden

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

BIND

Die bind-Methode entspricht der call-Methode, mit dem Unterschied, dass bind eine Funktion zurückgibt, die später durch Aufruf verwendet werden kann (sie wird nicht sofort aufgerufen).

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

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

printMyNAme() ist die Funktion, die die folgende Funktion aufruft

unten ist der Link für jsfiddle

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

38voto

John Slegers Punkte 41127

Beide Function.prototype.call() y Function.prototype.apply() Aufruf einer Funktion mit einem bestimmten this Wert und geben den Rückgabewert dieser Funktion zurück.

Function.prototype.bind() erstellt dagegen eine neue Funktion mit einer bestimmten this Wert, und gibt diese Funktion zurück, ohne sie auszuführen.

Nehmen wir also eine Funktion, die wie folgt aussieht:

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

Nehmen wir nun ein Objekt, das wie folgt aussieht:

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

Wir können unsere Funktion wie folgt an unser Objekt binden:

Obj.log = logProp.bind(Obj);

Jetzt können wir Obj.log irgendwo in unserem Code:

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

Wirklich interessant wird es, wenn Sie nicht nur einen Wert für this sondern auch für sein Argument prop :

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

Das können wir jetzt tun:

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

28voto

Siddhartha Punkte 1257

binden : Es bindet die Funktion an den angegebenen Wert und Kontext, führt die Funktion aber nicht aus. Um eine Funktion auszuführen, müssen Sie die Funktion aufrufen.

aufrufen : Er führt die Funktion mit dem angegebenen Kontext und den Parametern aus.

anwenden. : Er führt die Funktion mit dem angegebenen Kontext aus und Parameter als Array .

21voto

zangw Punkte 36978

Hier ist eine guter Artikel zur Veranschaulichung des Unterschieds zwischen bind() , apply() y call() fasst sie wie folgt zusammen.

  • bind() ermöglicht es uns, auf einfache Weise festzulegen, welches spezifische Objekt gebunden wird an diese 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 uns, Methoden zu übernehmen

    // 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 ist, dass wir eine neue Methode hinzufügen showData über die cars Objekt und wir wollen das vielleicht nicht tun, nur um eine Methode zu leihen, weil das Autoobjekt vielleicht schon eine Eigenschaft oder einen Methodennamen hat showData . Wir wollen sie nicht versehentlich überschreiben. Wie wir in unserer Diskussion über Apply y Call unten, ist es am besten, eine Methode zu entleihen, die entweder die Apply o Call Methode.

  • bind() erlauben uns, eine Funktion zu kurieren

    Funktion Currying , auch bekannt als Anwendung einer Teilfunktion ist die Verwendung eines Funktion (die ein oder mehrere Argumente akzeptiert), die eine neue Funktion zurückgibt, bei der einige der Argumente bereits gesetzt sind.

    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 verwenden bind() um dies zu striegeln greet función

    // 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() zum Einstellen diese Wert

    En apply , call y bind Methoden werden alle verwendet, um diesen Wert beim Aufruf einer Methode zu setzen, und sie tun es in leicht unterschiedlich, um eine direkte Kontrolle und Vielseitigkeit in unserem JavaScript-Code zu ermöglichen.

    En apply y call Methoden sind beim Setzen dieses Wertes fast identisch, mit dem Unterschied, dass Sie die Funktionsparameter an apply () comme ein Array , während Sie die Parameter einzeln auflisten um sie an die call () Methode.

    Hier ist ein Beispiel dafür call o apply zum Einstellen diese in der Rückruffunktion.

    // 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 ausleihen mit apply o call

    • Borrow-Array-Methoden

      Erstellen wir eine array-like Objekt und leihen Sie sich einige Array-Methoden, um mit unserem Array-ähnlichen Objekt zu arbeiten.

      // 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 Konvertierung arguments zu Array wie folgt

        // 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
  • Utilice apply() zur Ausführung variabler Polarität función

En Math.max ist ein Beispiel für eine Funktion mit variabler Polarität,

// 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 ein Array von Zahlen haben, das wir an Math.max ? Das können wir nicht tun:

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

Dies ist der Ort, an dem die apply () Methode hilft uns bei der Ausführung variable Funktionen . Anstelle des obigen Beispiels müssen wir das Zahlenfeld mit apply ( ) so:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X