Quelle est l'utilisation de la méthode JavaScript 'bind'?

651

À quoi sert bind()en JavaScript?

Sandeep Kumar
la source
8
Mon cas d'utilisation standard:select = document.querySelector.bind(document)
ceving
1
^ Et pour tous ceux qui se demandent, la raison pour laquelle cela est nécessaire est parce thisque, autrement, ferait référence à windowl'objet global. Avec document.querySelector.bind(document), nous veillons à ce que selectl » thisfait référence à document, et non window. Quelqu'un me corrige si j'ai mal compris cela.
AleksandrH

Réponses:

614

Bind crée une nouvelle fonction qui forcera l' thisintérieur de la fonction à être le paramètre transmis bind().

Voici un exemple qui montre comment utiliser bindpour passer une méthode membre qui a le bon this:

var myButton = {
  content: 'OK',
  click() {
    console.log(this.content + ' clicked');
  }
};

myButton.click();

var looseClick = myButton.click;
looseClick(); // not bound, 'this' is not myButton - it is the globalThis

var boundClick = myButton.click.bind(myButton);
boundClick(); // bound, 'this' is myButton

Qui imprime:

OK clicked
undefined clicked
OK clicked

Vous pouvez également ajouter des paramètres supplémentaires après le paramètre 1st ( this) et bindtransmettre ces valeurs à la fonction d'origine. Tous les paramètres supplémentaires que vous transmettez ultérieurement à la fonction liée seront transmis après les paramètres liés:

// Example showing binding some parameters
var sum = function(a, b) {
  return a + b;
};

var add5 = sum.bind(null, 5);
console.log(add5(10));

Qui imprime:

15

Consultez la fonction JavaScript bind pour plus d'informations et des exemples interactifs.

Mise à jour: ECMAScript 2015 ajoute la prise en charge des =>fonctions. =>les fonctions sont plus compactes et ne modifient pas le thispointeur de leur portée de définition, vous n'aurez donc pas besoin de l'utiliser bind()aussi souvent. Par exemple, si vous vouliez qu'une fonction Buttondu premier exemple connecte le clickrappel à un événement DOM, les méthodes suivantes sont toutes valides:

var myButton = {
  ... // As above
  hookEvent(element) {
    // Use bind() to ensure 'this' is the 'this' inside click()
    element.addEventListener('click', this.click.bind(this));
  }
};

Ou:

var myButton = {
  ... // As above
  hookEvent(element) {
    // Use a new variable for 'this' since 'this' inside the function
    // will not be the 'this' inside hookEvent()
    var me = this;
    element.addEventListener('click', function() { me.click() });
  }
};    

Ou:

var myButton = {
  ... // As above
  hookEvent(element) {
    // => functions do not change 'this', so you can use it directly
    element.addEventListener('click', () => this.click());
  }
};
nkron
la source
6
Excellente explantation, mais j'ai du mal à trouver des exemples où je voudrais utiliser la troisième option que vous avez décrite au lieu de la première option. Pouvez-vous décrire des situations où vous avez ressenti le besoin d'utiliser la troisième option?
Darryl
5
Je ne pense pas avoir déjà utilisé bind autre que pour lier 'this'. L'autre forme est connue sous le nom d' application partielle et est assez courante dans les langages fonctionnels. J'imagine qu'il est inclus pour être complet.
nkron
43
Si quelqu'un se demande pourquoi looseClick () n'est pas lié à myButton, c'est parce que "ceci" fait référence à l'objet qui appelle la fonction (looseClick ()). L'objet qui invoque looseClick () est l'objet global.
pokero
4
@Darryl - Une des raisons serait de transmettre des paramètres aux gestionnaires d'événements. Si vous avez ce code de réaction:, var Note = React.createClass({ add: function(text){ ... }, render: function () { return <button onClick={this.add.bind(null, "New Note")}/> } }alors lorsque le bouton est cliqué, il passera un texte de paramètre "New Note" à la addméthode.
P. Myer Nore
2
"Vous pouvez également ajouter des paramètres supplémentaires après le 1er paramètre et bind transmettra ces valeurs à la fonction d'origine avant de transmettre les paramètres supplémentaires que vous transmettez à la fonction liée:" Cette formulation est source de confusion.
Ken Ingram
271

L'utilisation la plus simple de bind()est de créer une fonction qui, quelle que soit la façon dont elle est appelée, est appelée avec une thisvaleur particulière .

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

module.getX(); // 81

var getX = module.getX;
getX(); // 9, because in this case, "this" refers to the global object

// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
boundGetX(); // 81

Veuillez consulter ce lien pour plus d'informations

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Renganathan MG
la source
38
La meilleure introduction à bind () que j'ai jamais vue.
thomasfl
3
Excellente réponse, car votre exemple ne nécessite pas de connaissances sur les fonctionnalités linguistiques (par exemple prototype) qui pourraient être nouvelles pour les débutants.
Edward
1
succinct & très clair!
papigee
172

lier permet-

  • définissez la valeur de "this" sur un objet spécifique. Cela devient très utile, car parfois ce n'est pas ce que l'on souhaite.
  • méthodes de réutilisation
  • curry une fonction

Par exemple, vous avez une fonction pour déduire les frais de club mensuels

function getMonthlyFee(fee){
  var remaining = this.total - fee;
  this.total = remaining;
  return this.name +' remaining balance:'+remaining;
}

Vous souhaitez maintenant réutiliser cette fonction pour un autre membre du club. Notez que les frais mensuels varient d'un membre à l'autre.

Imaginons que Rachel ait un solde de 500 et une cotisation mensuelle de 90.

var rachel = {name:'Rachel Green', total:500};

Maintenant, créez une fonction qui peut être utilisée encore et encore pour déduire les frais de son compte chaque mois

//bind
var getRachelFee = getMonthlyFee.bind(rachel, 90);
//deduct
getRachelFee();//Rachel Green remaining balance:410
getRachelFee();//Rachel Green remaining balance:320

Désormais, la même fonction getMonthlyFee peut être utilisée pour un autre membre avec des frais d'adhésion différents. Par exemple, Ross Geller a un solde de 250 et des frais mensuels de 25

var ross = {name:'Ross Geller', total:250};
//bind
var getRossFee = getMonthlyFee.bind(ross, 25);
//deduct
getRossFee(); //Ross Geller remaining balance:225
getRossFee(); //Ross Geller remaining balance:200
Jhankar Mahbub
la source
9
Dans votre exemple, je pense que je serais enclin à configurer un objet membre instancié avec le nouveau mot clé où chaque membre avait ses propres propriétés / méthodes. Ensuite, c'est simplement une question de ross.getMonthlyFee (25). Cet exemple était-il juste pour démontrer l'utilisation de bind () ou y a-t-il un avantage à votre approche?
Darryl
j'adore le curry une fonction!
Jerry Liu
je ne sais pas, mais je ferais var getRachelFee = getMonthlyFee (rachel, 90); Et la fonction serait la fonction getMonthlyFee (membre, frais) {} quelque chose dans le sens.
Miguel
1
@KhanSharp Votre réponse est correcte, mais ce sont vos références aux amis de la série télévisée qui me font commenter et voter. Merci pour votre réponse 🤗.
Saurabh Lende
79

Depuis les documents MDN sur Function.prototype.bind():

La méthode bind () crée une nouvelle fonction qui, lorsqu'elle est appelée, a son this mot-clé défini sur la valeur fournie, avec une séquence donnée d'arguments précédant ceux fournis lorsque la nouvelle fonction est appelée.

Alors qu'est-ce que cela signifie?!

Eh bien, prenons 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

Cela fonctionne, car nous avons lié la valeur de thisà notre objet Obj.


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

Contrairement à avec Obj.log, nous ne devons pas passer xou y, parce que nous avons passé ces valeurs lorsque nous avons fait notre liaison.

John Slegers
la source
9
Cette réponse devrait recevoir plus d'amour. Bien expliqué.
Chax
Très bonne combinaison d'aperçu général et d'exemple spécifique.
Ken Ingram
Où est le bouton qui déclenche 100 coups droits?
kushalvm
Avec cela, je recommanderais également de lire la section des documents MDN des fonctions partiellement appliquées pour comprendre l'utilisation de la liaison "null". Il devrait fermer les portes pour la plupart de l'utilisation de bind. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
kushalvm
23

Variables a des portées locales et mondiales. Supposons que nous ayons deux variables du même nom. L'un est défini globalement et l'autre est défini à l'intérieur d'une fermeture de fonction et nous voulons obtenir la valeur variable qui se trouve à l'intérieur de la fermeture de fonction. Dans ce cas, nous utilisons cette méthode bind (). Veuillez voir l'exemple simple ci-dessous:

var x = 9; // this refers to global "window" object here in the browser
var person = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

var y = person.getX; // It will return 9, because it will call global value of x(var x=9).

var x2 = y.bind(person); // It will return 81, because it will call local value of x, which is defined in the object called person(x=81).

document.getElementById("demo1").innerHTML = y();
document.getElementById("demo2").innerHTML = x2();
<p id="demo1">0</p>
<p id="demo2">0</p>

Krati agarwal
la source
18

Sommaire:

La bind()méthode prend un objet comme premier argument et crée une nouvelle fonction. Lorsque la fonction est invoquée, la valeur de thisdans le corps de la fonction sera l'objet qui a été passé comme argument dans la bind()fonction.

Comment ça thismarche dans JS quand même

La valeur de thisen javascript dépend dépend toujours de quel objet la fonction est appelée. La valeur de ceci fait toujours référence à l'objet à gauche du point d'où la fonction est appelée . Dans le cas de la portée mondiale, c'est window(ou globalen nodeJS). Seulement call, applyet bindpeut modifier différemment cette liaison. Voici un exemple pour montrer comment fonctionne ce mot-clé:

let obj = {
  prop1: 1,
  func: function () { console.log(this); } 
}

obj.func();   // obj left of the dot so this refers to obj

const customFunc = obj.func;  // we store the function in the customFunc obj

customFunc();  // now the object left of the dot is window, 
               // customFunc() is shorthand for window.customFunc()
               // Therefore window will be logged

Comment la liaison est-elle utilisée?

Bind peut aider à surmonter les difficultés avec le thismot - clé en ayant un objet fixe auquel il thisfera référence. Par exemple:

var name = 'globalName';

const obj = {
  name: 'myName',
  sayName: function () { console.log(this.name);}
}

const say = obj.sayName; // we are merely storing the function the value of this isn't magically transferred

say(); // now because this function is executed in global scope this will refer to the global var

const boundSay = obj.sayName.bind(obj); // now the value of this is bound to the obj object

boundSay();  // Now this will refer to the name in the obj object: 'myName'

Une fois que la fonction est liée à une thisvaleur particulière , nous pouvons la faire circuler et même la mettre sur les propriétés d'autres objets. La valeur de thisrestera la même.

Willem van der Veen
la source
3
Vos commentaires dans votre code sur le objest l'objet parce qu'il est à gauche du point et windowl'objet parce qu'il est un raccourci pour window.custFunc()et windowest à gauche du point était très perspicace pour moi.
nzaleski
12

Je vais expliquer la liaison théorique et pratique

bind en javascript est une méthode - Function.prototype.bind. bind est une méthode. Il est appelé prototype de fonction. Cette méthode crée une fonction dont le corps est similaire à la fonction sur laquelle elle est appelée mais le 'this' fait référence au premier paramètre passé à la méthode bind. Sa syntaxe est

     var bindedFunc = Func.bind(thisObj,optionsArg1,optionalArg2,optionalArg3,...);

Exemple:--

  var checkRange = function(value){
      if(typeof value !== "number"){
              return false;
      }
      else {
         return value >= this.minimum && value <= this.maximum;
      }
  }

  var range = {minimum:10,maximum:20};

  var boundedFunc = checkRange.bind(range); //bounded Function. this refers to range
  var result = boundedFunc(15); //passing value
  console.log(result) // will give true;
dinesh_malhotra
la source
Il transforme fondamentalement tout ce qui se trouve à l'intérieur de la fonction en n'importe quel objet que vous passez, n'est-ce pas?
Harvey Lin
11

La méthode bind () crée une nouvelle instance de fonction dont cette valeur est liée à la valeur passée dans bind (). Par exemple:

   window.color = "red"; 
   var o = { color: "blue" }; 
   function sayColor(){ 
       alert(this.color); 
   } 
   var objectSayColor = sayColor.bind(o); 
   objectSayColor(); //blue 

Ici, une nouvelle fonction appelée objectSayColor () est créée à partir de sayColor () en appelant bind () et en passant l'objet o. La fonction objectSayColor () a cette valeur équivalente à o, donc l'appel de la fonction, même en tant qu'appel global, entraîne l'affichage de la chaîne «bleu».

Référence: Nicholas C. Zakas - JAVASCRIPT® PROFESSIONNEL POUR LES DÉVELOPPEURS WEB

Otti
la source
exemple concis et laconique
Ahmad Sharif
9

Création d'une nouvelle fonction en liant des arguments à des valeurs

La bindméthode crée une nouvelle fonction à partir d'une autre fonction avec un ou plusieurs arguments liés à des valeurs spécifiques, y compris l' thisargument implicite .

Application partielle

Ceci est un exemple de application partielle . Normalement, nous fournissons une fonction avec tous ses arguments qui donne une valeur. C'est ce qu'on appelle l'application de fonction. Nous appliquons la fonction à ses arguments.

Une fonction d'ordre supérieur (HOF)

L'application partielle est un exemple de fonction d'ordre supérieur (HOF) car elle donne une nouvelle fonction avec moins d'arguments.

Liaison de plusieurs arguments

Vous pouvez utiliser bindpour transformer des fonctions avec plusieurs arguments en nouvelles fonctions.

function multiply(x, y) { 
    return x * y; 
}

let multiplyBy10 = multiply.bind(null, 10);
console.log(multiplyBy10(5));

Conversion de la méthode d'instance en fonction statique

Dans le cas d'utilisation le plus courant, lorsqu'elle est appelée avec un seul argument, la bindméthode crée une nouvelle fonction dont la thisvaleur est liée à une valeur spécifique. En effet, cela transforme une méthode d'instance en une méthode statique.

function Multiplier(factor) { 
    this.factor = factor;
}

Multiplier.prototype.multiply = function(x) { 
    return this.factor * x; 
}

function ApplyFunction(func, value) {
    return func(value);
}

var mul = new Multiplier(5);

// Produces garbage (NaN) because multiplying "undefined" by 10
console.log(ApplyFunction(mul.multiply, 10));

// Produces expected result: 50
console.log(ApplyFunction(mul.multiply.bind(mul), 10));

Implémentation d'un rappel avec état

L'exemple suivant montre comment l'utilisation de la liaison de thispeut permettre à une méthode objet d'agir comme un rappel qui peut facilement mettre à jour l'état d'un objet.

function ButtonPressedLogger()
{
   this.count = 0;
   this.onPressed = function() {
      this.count++;
      console.log("pressed a button " + this.count + " times");
   }
   for (let d of document.getElementsByTagName("button"))
      d.onclick = this.onPressed.bind(this);
}

new ButtonPressedLogger();      
<button>press me</button>
<button>no press me</button>

cdiggins
la source
6

Comme mentionné, Function.bind()vous permet de spécifier le contexte dans lequel la fonction s'exécutera (c'est-à-dire, vous permet de passer dans quel objet le thismot clé se résoudra dans le corps de la fonction.

Un couple de méthodes API de boîte à outils analogues qui effectuent un service similaire:

jQuery.proxy ()

Dojo.hitch ()

mtyson
la source
3
/**
 * Bind is a method inherited from Function.prototype same like call and apply
 * It basically helps to bind a function to an object's context during initialisation 
 * 
 * */

window.myname = "Jineesh";  
var foo = function(){ 
  return this.myname;
};

//IE < 8 has issues with this, supported in ecmascript 5
var obj = { 
    myname : "John", 
    fn:foo.bind(window)// binds to window object
}; 
console.log( obj.fn() ); // Returns Jineesh
Jineesh
la source
3

Considérez le programme simple ci-dessous,

//we create object user
let User = { name: 'Justin' };

//a Hello Function is created to Alert the object User 
function Hello() {
  alert(this.name);
}

//since there the value of this is lost we need to bind user to use this keyword
let user = Hello.bind(User);
user();

//we create an instance to refer the this keyword (this.name);
BontéGoodness Chi
la source
2

La fonction bind crée une nouvelle fonction avec le même corps de fonction que la fonction qu'elle appelle. Elle est appelée avec l'argument this .pourquoi nous utilisons bind fun. : chaque fois qu'une nouvelle instance est créée et que nous devons utiliser la première instance initiale, nous utilisons alors bind fun. Nous ne pouvons pas remplacer le bind fun. il stocke simplement l'objet initial de la classe.

setInterval(this.animate_to.bind(this), 1000/this.difference);
user2485861
la source
0

Une autre utilisation est que vous pouvez passer une fonction liée comme argument à une autre fonction qui fonctionne dans un autre contexte d'exécution.

var name = "sample";
function sample(){
  console.log(this.name);
}
var cb = sample.bind(this);

function somefunction(cb){
  //other code
  cb();
}
somefunction.call({}, cb);
Amar T
la source
0

Exemple simple

function lol(text) {
    console.log(this.name, text);
}

lol(); // undefined undefined
lol('first'); // undefined first
lol.call({name: 'karl'}); // karl undefined
lol.call({name: 'karl'}, 'second'); // karl second
lol.apply({name: 'meg'}); // meg undefined
lol.apply({name: 'meg'}, ['third']); // meg third
const newLol = lol.bind({name: 'bob'});
newLol(); // bob undefined
newLol('fourth'); // bob fourth
K - La toxicité du SO augmente.
la source
0

Méthode de liaison

Une implémentation de liaison pourrait ressembler à ceci:

Function.prototype.bind = function () {
  const self = this;
  const args = [...arguments];
  const context = args.shift();

  return function () {
    return self.apply(context, args.concat([...arguments]));
  };
};

La fonction de liaison peut prendre n'importe quel nombre d'arguments et renvoyer une nouvelle fonction .

La nouvelle fonction appellera la fonction d'origine à l'aide de la Function.prototype.applyméthode JS .
La applyméthode utilisera le premier argument passé à la fonction cible comme contexte ( this), et le deuxième argument de tableau de la applyméthode sera une combinaison du reste des arguments de la fonction cible, concaténé avec les arguments utilisés pour appeler le retour fonction (dans cet ordre).

Un exemple peut ressembler à ceci:

function Fruit(emoji) {
  this.emoji = emoji;
}

Fruit.prototype.show = function () {
  console.log(this.emoji);
};

const apple = new Fruit('🍎');
const orange = new Fruit('🍊');

apple.show();  // 🍎
orange.show(); // 🍊

const fruit1 = apple.show;
const fruit2 = apple.show.bind();
const fruit3 = apple.show.bind(apple);
const fruit4 = apple.show.bind(orange);

fruit1(); // undefined
fruit2(); // undefined
fruit3(); // 🍎
fruit4(); // 🍊

Lior Elrom
la source
0

Explication simple:

bind () crée une nouvelle fonction, une nouvelle référence à une fonction qu'elle vous renvoie.

En paramètre après ce mot-clé, vous passez le paramètre que vous souhaitez préconfigurer. En fait, il ne s'exécute pas immédiatement, se prépare simplement à l'exécution.

Vous pouvez préconfigurer autant de paramètres que vous le souhaitez.

Exemple simple pour comprendre la liaison:

function calculate(operation) {
  if (operation === 'ADD') {
   alert('The Operation is Addition');
  } else if (operation === 'SUBTRACT') {
   alert('The Operation is Subtraction');
  }
}

addBtn.addEventListener('click', calculate.bind(this, 'ADD'));
subtractBtn.addEventListener('click', calculate.bind(this, 'SUBTRACT'));
Shivu
la source
-1

bind est une fonction disponible dans le prototype de script java, comme son nom l'indique, bind est utilisé pour lier votre appel de fonction au contexte dans lequel vous traitez, par exemple:

    var rateOfInterest='4%';
    var axisBank=
    {
    rateOfInterest:'10%',
    getRateOfInterest:function()
    {
    return this.rateOfInterest;
    }
    }
    axisBank.getRateOfInterest() //'10%' 


    let knowAxisBankInterest=axisBank.getRateOfInterest // when you want to assign the function call to a varaible we use this syntax
    knowAxisBankInterest(); // you will get output as '4%' here by default the function is called wrt global context

let knowExactAxisBankInterest=knowAxisBankInterest.bind(axisBank);     //so here we need bind function call  to its local context


    knowExactAxisBankInterest() // '10%' 

Thara
la source