Javascript appelle () et applique () vs bind ()?

794

Je le sais déjà applyet ce callsont des fonctions similaires qui se mettent en place this(contexte d'une fonction).

La différence est avec la façon dont nous envoyons les arguments (manuel vs tableau)

Question:

Mais quand dois-je utiliser la bind()méthode?

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
la source
9
Ce n'est pas de votre faute s'il y a des utilisateurs qui regardent les points de réputation du PO avant de poster une réponse ou de voter) :)
Gabriel Llamas
54
appeler et appliquer appeler une fonction tandis que bind crée une fonction. Cependant,call()vous passez des arguments individuellement etapply()sous forme de tableau d'arguments. Pour plus de détails, consultez la documentation liée qui devrait être en mesure de répondre complètement à votre question.
Non
3
kind of weird there is not an existing question about this :Le concernant. C'est probablement parce qu'il a bind()été ajouté après que les deux autres existaient déjà dans JavaScript 1.8.5 - ECMA-262, 5e édition. Bien que call()et apply()ont été autour depuis JavaScript 1.3 - ECMA-262 3rd Edition. SO a des questions sur eux comme: quelle est la différence entre appeler et postuler . Je ne fais que deviner, car je me le demandais moi-même.
Non
avez-vous besoin de ces méthodes (appeler, appliquer, lier) ici ?? sans cela, vous pouvez également appeler la méthode et cela pointera vers un objet uniquement
Mahi
consultez
techyaura

Réponses:

131

J'ai créé cette comparaison entre les objets de fonction, les appels de fonction call/applyet il y a bindun certain temps:

entrez la description de l'image ici

.bindvous permet de définir la thisvaleur maintenant tout en vous permettant d'exécuter la fonction à l'avenir , car elle renvoie un nouvel objet fonction.

Felix Kling
la source
779

À utiliser .bind()lorsque vous souhaitez que cette fonction soit appelée ultérieurement avec un certain contexte, utile dans les événements. Utilisez .call()ou .apply()lorsque vous souhaitez appeler la fonction immédiatement et modifiez le contexte.

Appeler / appliquer appelle immédiatement la fonction, tandis que bindrenvoie une fonction qui, lorsqu'elle sera exécutée ultérieurement, aura le contexte correct défini pour appeler la fonction d'origine. De cette façon, vous pouvez maintenir le contexte dans les rappels et les événements asynchrones.

Je le fais beaucoup:

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

Je l'utilise largement dans Node.js pour les rappels asynchrones pour lesquels je veux passer une méthode membre, mais je veux toujours que le contexte soit l'instance qui a lancé l'action asynchrone.

Une implémentation simple et naïve de bind serait comme:

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

Il y a plus à faire (comme passer d'autres arguments), mais vous pouvez en savoir plus à ce sujet et voir la véritable implémentation sur le MDN .

J'espère que cela t'aides.

Tchad
la source
2
@RoyiNamir qui est correct, vous pouvez utiliser la fonction "liée" retournée plus tard, et le contexte sera maintenu.
Chad
5
C'est exactement ce qui bindrevient.
Chad
@RoyiNamir Modifié ma réponse
Chad
4
Vous pouvez également utiliser bind pour les partiels, en passant des arguments avant l'appel de la fonction.
Andrew Kirkegaard
1
Vous réimplémentez simplement bind, il n'y a pas vraiment de différence. Quoi qu'il en soit, vous l'enveloppez simplement dans une fermeture qui a accès à une variable de portée qui contient le contexte. Votre code est essentiellement le polyfill que j'ai publié.
Chad
446

Ils attachent tous cela à la fonction (ou à l'objet) et la différence réside dans l'invocation de la fonction (voir ci-dessous).

l'appel attache ceci dans la fonction et exécute la fonction immédiatement:

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 attache ce en fonction et il doit être invoqué séparément comme ceci:

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"

ou comme ça:

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

appliquer est similaire à appeler, sauf qu'il prend un objet de type tableau au lieu de répertorier les arguments un par un:

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"                                     
CuriousSuperhero
la source
1
Est-ce à dire que la différence est que Bind est une fermeture?
Gregory R.
Vous venez de me renseigner sur la fonction d'arguments utilisée dans une fonction via votre extrait de code. Il est conseillé de mentionner "use strict"pour éviter de remplacer ces mots-clés réservés. +1.
RBT
@Max a accepté; J'ai soumis une modification dans laquelle "ceci" est faux ou n'a aucun sens jusqu'à ce que nous utilisions bind / call / apply
iono
1
Merci pour les suggestions d'amélioration. J'ai un peu modifié ma réponse. @iono Votre suggestion comportait des inexactitudes, je n'ai donc pas pu l'approuver, mais j'ai fait mes propres modifications dans la réponse. Espérons qu'il soit désormais plus complet.
CuriousSuperhero
200

Réponse sous forme SIMPLEST

  • L'appel appelle la fonction et vous permet de passer des arguments un par un.
  • Apply appelle la fonction et vous permet de passer des arguments sous forme de tableau.
  • Bind retourne une nouvelle fonction, vous permettant de passer dans ce tableau et n'importe quel nombre d'arguments.

Exemples d'application, d'appel et de liaison

Appel

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

Appliquer

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

Lier

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

Quand utiliser chacun

Appelez et postulez sont assez interchangeables. Décidez simplement s'il est plus facile d'envoyer un tableau ou une liste d'arguments séparés par des virgules.

Je me souviens toujours lequel est lequel en se rappelant que Call est pour une virgule (liste séparée) et Apply est pour Array.

Bind est un peu différent. Il renvoie une nouvelle fonction. Appel et application exécutent immédiatement la fonction actuelle.

La liaison est idéale pour beaucoup de choses. Nous pouvons l'utiliser pour curry des fonctions comme dans l'exemple ci-dessus. Nous pouvons prendre une simple fonction hello et la transformer en helloJon ou helloKelly. Nous pouvons également l'utiliser pour des événements comme onClick où nous ne savons pas quand ils seront renvoyés, mais nous savons quel contexte nous voulons qu'ils aient.

Référence: codeplanet.io

Amit Shah
la source
8
Réponse géniale, si c'était mon message de question, je vous coche.
AmerllicA
Dans callet apply, cela signifie-t-il que si vous ne disposez pas d'un thisà l'intérieur de la méthode, vous affecteriez le premier argument en tant que null?
Daryll Santos
1
@DaryllSantos, selon MDN: thisArg Facultatif. La valeur de ceci a fourni l'appel à une fonction. Notez que cela peut ne pas être la valeur réelle vue par la méthode: si la méthode est une fonction en mode non strict, null et undefined seront remplacés par l'objet global et les valeurs primitives seront converties en objets. Donc, si vous ne l'utilisez pas dans la fonction, cela n'a pas d'importance.
Amit Shah
4
call = = virgule, apply == array était une belle petite astuce de mémorisation
drlff
var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanFonctionne parfaitement bien et produit VM128: 4 Bonjour Jon Kuperman
Pratik
53

Il permet de définir la valeur de thisindépendamment de la façon dont la fonction est appelée. Ceci est très utile lorsque vous travaillez avec des rappels:

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

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

Pour obtenir le même résultat avec, callcela ressemblerait à ceci:

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

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
jantimon
la source
5
L'utilisation de ce .bind()que vous avez montré auparavant est incorrecte. Lorsque vous utilisez une fn.bind(obj)autre fonction sera retournée (pas celle que vous avez créée auparavant). Et il n'y a aucune capacité à changer la valeur de l' thisintérieur de la bindedfonction. Généralement, cela est utilisé pour l' thisassurance de rappel . Mais dans votre exemple - il n'y a aucune différence de résultat. Mais fn !== fn.bind(obj);remarquez cela.
ValeriiVasin
@InviS Je ne comprends pas votre commentaire - pourquoi n'y a-t-il pas de différence?
jantimon
2
La différence entre l'appel et l'application est. en appel, vous passez des arguments sous forme de chaînes séparées par des virgules, tandis qu'en application, vous pouvez passer des arguments sous forme de tableau. le reste sont les mêmes.
Ashish Yadav
des chaînes séparées par des virgules ?? passez juste les arguments séparés par des virgules !!
Sudhansu Choudhary
46

Supposons que nous ayons une multiplicationfonction

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

Permet de créer des fonctions standard en utilisant bind

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

Maintenant multiby2 (b) est égal à multiplication (2, b);

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

Et si je passe les deux paramètres dans bind

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

Maintenant, getSixAlways () est égal à multiplication (3,2);

getSixAlways();//6

même le passage du paramètre renvoie 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Cela crée une nouvelle fonction de multiplication et l'affecte à magicMultiplication.

Oh non, nous cachons la fonctionnalité de multiplication dans magicMultiplication.

appeler magicMultiplicationrenvoie un blancfunction b()

à l'exécution, cela fonctionne bien magicMultiplication(6,5); //30

Que diriez-vous d'appeler et d'appliquer?

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

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

En termes simples, bindcrée la fonction callet applyexécute la fonction alors qu'elle applyattend les paramètres dans le tableau

tk120404
la source
Très bien expliqué!
CatalinBerta
3
+1 pour "En termes simples, bindcrée la fonction callet applyexécute la fonction alors qu'elle applyattend les paramètres dans le tableau"
Josh Buchea
32

Les deux Function.prototype.call()et Function.prototype.apply()appeler une fonction avec une donnée de thisvaleur et retourner la valeur de retour de cette fonction.

Function.prototype.bind(), d'autre part, crée une nouvelle fonction avec une thisvaleur donnée et renvoie cette fonction sans l'exécuter.

Prenons donc une fonction qui ressemble à ceci:

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

Maintenant, prenons un objet qui ressemble à ceci:

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

Nous pouvons lier notre fonction à notre objet comme ceci:

Obj.log = logProp.bind(Obj);

Maintenant, nous pouvons exécuter Obj.logn'importe où dans notre code:

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

Là où cela devient vraiment intéressant, c'est quand vous liez non seulement une valeur pour this, mais aussi pour son argument prop:

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

Nous pouvons maintenant le faire:

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

bind : il lie la fonction avec la valeur et le contexte fournis mais n'exécute pas la fonction. Pour exécuter la fonction, vous devez appeler la fonction.

appel : il exécute la fonction avec le contexte et le paramètre fournis.

apply : il exécute la fonction avec le contexte et les paramètres fournis sous forme de tableau .

Siddhartha
la source
simple et humble!
Habeeb Perwad
18

Voici un bon article pour illustrer la différence entre bind(), apply()et call(), résumer comme ci - dessous.

  • bind()nous permet de définir facilement quel objet spécifique sera lié à cela lorsqu'une fonction ou une méthode est invoquée.

    // 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() nous permettent d'emprunter des méthodes

    // 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 problème avec cet exemple est que nous ajoutons une nouvelle méthode showDatasur l' carsobjet et que nous ne voulons peut-être pas le faire uniquement pour emprunter une méthode car l'objet cars peut déjà avoir une propriété ou un nom de méthode showData. Nous ne voulons pas l'écraser accidentellement. Comme nous le verrons dans notre discussion sur Applyet Callci - dessous, il est préférable d'emprunter une méthode en utilisant la méthode Applyou Call.

  • bind() nous permettent de curry une fonction

    Le curry de fonction , également appelé application de fonction partielle , est l'utilisation d'une fonction (qui accepte un ou plusieurs arguments) qui renvoie une nouvelle fonction avec certains des arguments déjà définis.

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

    Nous pouvons utiliser bind()pour curry cette greetfonction

    // 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()ou call()pour définir cette valeur

    Les apply, callet les bindméthodes sont tous utilisés pour définir la valeur lors de l' appel de cette méthode, et ils le font de façon légèrement différente pour permettre l' utilisation de contrôle direct et la polyvalence dans notre code JavaScript.

    Les applyet callméthodes sont presque identiques lors de la définition de la cette valeur , sauf que vous passez les paramètres de fonction apply ()comme un tableau , alors que vous devez lister les paramètres individuellement pour les passer à la call ()méthode.

    Voici un exemple d'utiliser callou applyde régler ce dans la fonction de rappel.

    // 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
  • Emprunter des fonctions avec applyoucall

    • Emprunter des méthodes de tableau

      Créons un array-likeobjet et empruntons quelques méthodes de tableau pour opérer sur notre objet de type tableau.

      // 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 autre cas courant est la conversion argumentsen tableau comme suit

        // 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"]
    • Emprunter d'autres méthodes

      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​
  • Utiliser apply()pour exécuter la fonction d' arité variable

C'est Math.maxun exemple de fonction d'arité variable,

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

Mais que se passe-t-il si nous avons un tableau de nombres à transmettre Math.max? Nous ne pouvons pas faire cela:

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

C'est là que la apply ()méthode nous aide à exécuter des fonctions variadiques . Au lieu de ce qui précède, nous devons passer le tableau de nombres en utilisant apply () ainsi:

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
la source
8

call / apply exécute la fonction immédiatement:

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

bind n'exécute pas la fonction immédiatement, mais retourne la fonction apply enveloppée (pour une exécution ultérieure):

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

Syntaxe

  • appel (thisArg, arg1, arg2, ...)
  • appliquer (thisArg, argsArray)
  • bind (thisArg [, arg1 [, arg2 [, ...]]])

Ici

  • thisArg est l'objet
  • argArray est un objet tableau
  • arg1, arg2, arg3, ... sont des arguments supplémentaires

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
la source
6

La différence fondamentale entre Call, Apply et Bind est:

Bind sera utilisé si vous souhaitez que votre contexte d'exécution apparaisse plus tard dans l'image.

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

Disons que je veux utiliser cette méthode dans une autre variable

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

Pour utiliser la référence de voiture dans une autre variable, vous devez utiliser

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

Parlons d'une utilisation plus étendue de la fonction de liaison

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

func();
// Number: 1

Pourquoi? Parce que maintenant func est lié avec Number 1, si nous n'utilisons pas bind dans ce cas, il pointera sur Global Object.

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

func();
// Object

Appel, Appliquer sont utilisés lorsque vous souhaitez exécuter l'instruction en même temps.

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
la source
4

Appelez appliquer et lier. et comment ils sont différents.

Permet d'apprendre à appeler et d'appliquer en utilisant n'importe quelle terminologie quotidienne.

Vous avez trois automobiles your_scooter , your_car and your_jetqui démarrent avec le même mécanisme (méthode). Nous avons créé un objet automobileavec une méthode 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");
    }
}

Permet de comprendre quand l'appel est appliqué et d'appliquer. Supposons que vous êtes ingénieur et que vous l'avez fait your_scooter, your_caret your_jetque vous ne soyez pas venu avec un push_button_engine_start et que vous souhaitiez utiliser un tiers push_button_engineStart.

Si vous exécutez les lignes de code suivantes, elles donneront une erreur. POURQUOI?

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

Ainsi, l'exemple ci-dessus donne avec succès à votre_scooter, votre_voiture, votre_jet une caractéristique de l'objet automobile.

Approfondissons Ici, nous allons diviser la ligne de code ci-dessus. automobile.push_button_engineStartnous aide à utiliser la méthode.

De plus, nous utilisons appliquer ou appeler en utilisant la notation par points. automobile.push_button_engineStart.apply()

Maintenant, appliquez et appelez accepter deux paramètres.

  1. le contexte
  2. arguments

Nous définissons donc ici le contexte dans la dernière ligne de code.

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

La différence entre l'appel et l'application est simplement que l'application accepte les paramètres sous la forme d'un tableau tandis que l'appel peut simplement accepter une liste d'arguments séparés par des virgules.

qu'est-ce que la fonction JS Bind?

Une fonction de liaison est fondamentalement qui lie le contexte de quelque chose et le stocke ensuite dans une variable pour une exécution ultérieure.

Rendons notre exemple précédent encore meilleur. Plus tôt, nous avons utilisé une méthode appartenant à l'objet automobile et l'avons utilisée pour équiper your_car, your_jet and your_scooter. Imaginons maintenant que nous voulons donner un séparé push_button_engineStartséparément pour démarrer nos automobiles individuellement à tout stade ultérieur de l'exécution que nous souhaitons.

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

toujours pas satisfait?

Disons-le clairement comme une larme. Il est temps d'expérimenter. Nous allons revenir pour appeler et appliquer l'application de la fonction et essayer de stocker la valeur de la fonction comme référence.

L'expérience ci-dessous échoue parce que call et apply sont invoqués immédiatement, par conséquent, nous n'atteignons jamais le stade de stockage d'une référence dans une variable qui est l'endroit où la fonction de liaison vole la vedette

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

Sagar Munjal
la source
3

Appel: appel invoque la fonction et vous permet de passer des arguments un par un

Apply: Apply invoque la fonction et vous permet de passer des arguments sous forme de tableau

Bind: Bind renvoie une nouvelle fonction, vous permettant de transmettre un tableau this et un nombre quelconque d'arguments.

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
la source
2

call (): - Ici, nous passons les arguments de la fonction individuellement, pas dans un format de tableau

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 (): - Ici, nous passons les arguments de la fonction dans un format de tableau

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

lier() :--

       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
la source
2

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

JavaScript s'applique ()

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

** les fonctions call et apply sont des appels d'appel différentiels, mais un tableau take comme: [1,2,3] **

Liaison JavaScript ()

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

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()
Shuvro
la source
1

Imaginez, la liaison n'est pas disponible. vous pouvez facilement le construire comme suit:

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

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

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

Le concept principal derrière toutes ces méthodes est la fouille de fonction .

L'emprunt de fonctions nous permet d'utiliser les méthodes d'un objet sur un objet différent sans avoir à faire une copie de cette méthode et à la conserver à deux endroits distincts. Il est accompli grâce à l'utilisation de. appel() , . appliquer (), ou. bind (), qui existent tous pour définir explicitement cela sur la méthode que nous empruntons

  1. L'appel appelle immédiatement la fonction et vous permet de passer les arguments un par un
  2. Apply appelle immédiatement la fonction et vous permet de passer des arguments sous forme de tableau .
  3. Bind renvoie une nouvelle fonction, et vous pouvez l'appeler / l'appeler à tout moment en appelant une fonction.

Voici un exemple de toutes ces méthodes

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

APPEL

le premier argument, par exemple, le nom dans la méthode d'appel est toujours une référence à (cette) variable et cette dernière sera une variable de fonction

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

APPLIQUER

la méthode apply est la même que la méthode call, la seule différence est que les arguments de la fonction sont passés dans la liste des tableaux

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

LIER

La méthode de liaison est identique à l'appel, sauf que la liaison renvoie une fonction qui peut être utilisée plus tard en l'invoquant (ne l'appelle pas immédiatement)

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

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

printMyNAme () est la fonction qui appelle la fonction

ci-dessous est le lien pour jsfiddle

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

Arham Chowdhury
la source
-1

Je pense que les mêmes endroits sont: ils peuvent tous changer la valeur de cette fonction. Les différences sont: la fonction bind retournera une nouvelle fonction en conséquence; les méthodes call et apply exécuteront la fonction immédiatement, mais apply peut accepter un tableau en tant que paramètres, et il analysera le tableau séparément. De plus, la fonction de liaison peut être Currying.

Xin Tao
la source
-3

La fonction de liaison doit être utilisée lorsque nous voulons assigner une fonction avec un contexte particulier, par exemple.

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

dans l'exemple ci-dessus si nous appelons la fonction demo.setValue () et transmettons directement la fonction this.getValue, alors il n'appelle pas la fonction demo.setValue directement car cela dans setTimeout fait référence à l'objet fenêtre, nous devons donc passer le contexte de l'objet de démonstration à this.getValue fonction utilisant bind. cela signifie que nous ne transmettons que la fonction avec le contexte de l'objet de démonstration et non la fonction d'appel.

J'espère que tu comprends .

pour plus d'informations s'il vous plaît se référer à la fonction de liaison javascript connaître en détail

user7339156
la source