Was ist die Verwendung der JavaScript-Bindemethode?


649

Was ist die Verwendung bind()in JavaScript?


8
Mein Standard-Anwendungsfall:select = document.querySelector.bind(document)
am

1
^ Und für alle, die sich fragen, ist der Grund, der benötigt wird, weil er thissich sonst auf windowdas globale Objekt beziehen würde . Mit document.querySelector.bind(document)stellen wir sicher , dass select‚s thisbezieht sich auf document, und nicht zu window. Jemand korrigiert mich, wenn ich das falsch verstanden habe.
AleksandrH

Antworten:


612

Bind erstellt eine neue Funktion, die erzwingt, dass das thisInnere der Funktion der Parameter ist, an den übergeben wird bind().

Hier ist ein Beispiel, das zeigt, wie bindeine Member-Methode übergeben wird, die das Richtige hat 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

Welches druckt aus:

OK clicked
undefined clicked
OK clicked

Sie können auch zusätzliche Parameter nach dem Parameter 1st ( this) hinzufügen und binddiese Werte an die ursprüngliche Funktion übergeben. Alle zusätzlichen Parameter, die Sie später an die gebundene Funktion übergeben, werden nach den gebundenen Parametern übergeben:

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

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

Welches druckt aus:

15

Weitere Informationen und interaktive Beispiele finden Sie unter JavaScript-Funktionsbindung .

Update: ECMAScript 2015 bietet Unterstützung für =>Funktionen. =>Funktionen sind kompakter und ändern den thisZeiger nicht von ihrem definierten Bereich, sodass Sie ihn möglicherweise nicht bind()so oft verwenden müssen. Wenn Sie beispielsweise eine Funktion Buttonaus dem ersten Beispiel aktivieren clickmöchten, um den Rückruf mit einem DOM-Ereignis zu verbinden, sind die folgenden Möglichkeiten gültig:

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

Oder:

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

Oder:

var myButton = {
  ... // As above
  hookEvent(element) {
    // => functions do not change 'this', so you can use it directly
    element.addEventListener('click', () => this.click());
  }
};

6
Hervorragende Explantation, aber ich habe Schwierigkeiten, Beispiele zu finden, bei denen ich die von Ihnen beschriebene dritte Option anstelle der ersten Option verwenden möchte. Können Sie Situationen beschreiben, in denen Sie die dritte Option nutzen mussten?
Darryl

5
Ich glaube nicht, dass ich jemals eine andere Bindung verwendet habe, als "dies" zu binden. Die andere Form ist als Teilanwendung bekannt und kommt in funktionalen Sprachen häufig vor. Ich stelle mir vor, es ist der Vollständigkeit halber enthalten.
nkron

41
Falls sich jemand fragt, warum loseClick () nicht an myButton gebunden ist, liegt dies daran, dass "dies" sich auf das Objekt bezieht, das die Funktion aufruft (loseClick ()). Das Objekt, das loseClick () aufruft, ist das globale Objekt.
Pokero

4
@Darryl - Ein Grund dafür wäre, Parameter von Ereignishandlern zu übergeben. Wenn Sie diesen Reaktionscode haben: Wenn Sie auf var Note = React.createClass({ add: function(text){ ... }, render: function () { return <button onClick={this.add.bind(null, "New Note")}/> } }die Schaltfläche klicken, wird der addMethode ein Parametertext "New Note" übergeben .
P. Myer Nore

2
"Sie können auch zusätzliche Parameter nach dem ersten Parameter hinzufügen, und bind übergibt diese Werte an die ursprüngliche Funktion, bevor Sie die zusätzlichen Parameter übergeben, die Sie an die gebundene Funktion übergeben:" Dieser Wortlaut ist verwirrend.
Ken Ingram

270

Am einfachsten bind()ist es, eine Funktion zu erstellen, die unabhängig von ihrem Aufruf mit einem bestimmten thisWert aufgerufen wird.

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

Bitte beziehen Sie sich auf diesen Link für weitere Informationen

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


37
Die beste Einführung in bind (), die ich je gesehen habe.
Thomasfl

3
Gute Antwort, da Ihr Beispiel keine Kenntnisse über Sprachfunktionen (z. B. prototype) erfordert , die für Anfänger möglicherweise neu sind.
Edward

1
prägnant und sehr klar!
Papigee vor

172

binden erlaubt-

  • Setzen Sie den Wert von "this" auf ein bestimmtes Objekt. Dies wird sehr hilfreich , da manchmal das ist nicht das, was beabsichtigt ist.
  • Wiederverwendungsmethoden
  • Curry eine Funktion

Sie haben beispielsweise die Möglichkeit, monatliche Clubgebühren abzuziehen

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

Jetzt möchten Sie diese Funktion für ein anderes Clubmitglied wiederverwenden. Beachten Sie, dass die monatliche Gebühr von Mitglied zu Mitglied unterschiedlich ist.

Stellen wir uns vor, Rachel hat einen Kontostand von 500 und einen monatlichen Mitgliedsbeitrag von 90.

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

Erstellen Sie jetzt eine Funktion, mit der Sie die Gebühr jeden Monat immer wieder von ihrem Konto abziehen können

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

Jetzt kann dieselbe Funktion getMonthlyFee für ein anderes Mitglied mit einem anderen Mitgliedsbeitrag verwendet werden. Zum Beispiel hat Ross Geller ein Guthaben von 250 und eine monatliche Gebühr von 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

9
In Ihrem Beispiel würde ich wahrscheinlich ein Mitgliedsobjekt einrichten, das mit dem neuen Schlüsselwort instanziiert wurde, wobei jedes Mitglied seine eigenen Eigenschaften / Methoden hatte. Dann geht es einfach um ross.getMonthlyFee (25). War dieses Beispiel nur, um die Verwendung von bind () zu demonstrieren, oder hat Ihr Ansatz einen Vorteil?
Darryl

liebe das Curry eine Funktion eins!
Jerry Liu

Ich weiß es nicht, aber ich würde es tun. var getRachelFee = getMonthlyFee (rachel, 90); Und Funktion wäre Funktion getMonthlyFee (Mitglied, Gebühr) {} etwas in der Richtung.
Miguel

1
@ KhanSharp Ihre Antwort ist richtig, aber es sind Ihre Verweise auf TV-Serien Friends, die mich dazu bringen, Kommentare abzugeben und zu stimmen. Vielen Dank für Ihre Antwort 🤗.
Saurabh Lende

79

Von der MDN - Dokumentation auf Function.prototype.bind():

Die bind () -Methode erstellt eine neue Funktion, deren Schlüsselwort beim Aufruf auf den angegebenen Wert gesetzt wird, wobei eine bestimmte Folge von Argumenten vor jeder angegebenen steht, die beim Aufruf der neuen Funktion angegeben wird.

Was bedeutet das?!

Nehmen wir 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

Dies funktioniert, weil wir den Wert von thisan unser Objekt gebunden haben Obj.


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

Anders als bei Obj.logmüssen wir nicht übergeben xoder y, weil wir diese Werte bei unserer Bindung übergeben haben.


9
Diese Antwort sollte mehr Liebe bekommen. Gut erklärt.
Chax

Sehr gute Kombination aus allgemeiner Übersicht und spezifischem Beispiel.
Ken Ingram

Wo ist der Knopf, der gerade 100 Ups hochschießt?
Kushalvm

In diesem Zusammenhang würde ich auch empfehlen, den Abschnitt MDN-Dokumente der teilweise angewendeten Funktionen zu lesen , um die Verwendung von bind "null" zu verstehen. Es sollte die Tore für den größten Teil der Bindungsnutzung schließen. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
kushalvm

23

Variablen haben lokale und globale Bereiche. Nehmen wir an, wir haben zwei Variablen mit demselben Namen. Einer ist global definiert und der andere ist innerhalb eines Funktionsabschlusses definiert, und wir möchten den Variablenwert erhalten, der sich innerhalb des Funktionsabschlusses befindet. In diesem Fall verwenden wir diese bind () -Methode. Bitte sehen Sie das einfache Beispiel unten:

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>


18

Zusammenfassung:

Die bind()Methode nimmt ein Objekt als erstes Argument und erstellt eine neue Funktion. Wenn die Funktion aufgerufen wird, ist der Wert von thisim Funktionskörper das Objekt, das als Argument in der bind()Funktion übergeben wurde.

Wie funktioniert das überhaupt thisin JS?

Der Wert von thisin Javascript hängt immer davon ab, welches Objekt die Funktion aufruft. Der Wert bezieht sich immer auf das Objekt links vom Punkt, von dem aus die Funktion aufgerufen wird . Im Falle des globalen Geltungsbereichs ist dies window(oder globalin nodeJS). Nur call, applyund bindkann anders die diese Bindung ändern. Hier ist ein Beispiel, um zu zeigen, wie dieses Schlüsselwort funktioniert:

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

Wie wird bind verwendet?

Bind kann helfen, Schwierigkeiten mit dem thisSchlüsselwort zu überwinden, indem ein festes Objekt vorhanden ist, auf thisdas verwiesen wird. Zum Beispiel:

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'

Sobald die Funktion an einen bestimmten thisWert gebunden ist, können wir sie weitergeben und sogar Eigenschaften anderer Objekte zuweisen. Der Wert von thiswird gleich bleiben.


3
Ihre Kommentare in Ihrem Code über das objist das Objekt, weil es vom Punkt übrig bleibt und windowdas Objekt, weil es eine Abkürzung für window.custFunc()und windowlinks vom Punkt ist, waren für mich sehr aufschlussreich.
Nzaleski

12

Ich werde das Binden sowohl theoretisch als auch praktisch erklären

Binden in Javascript ist eine Methode - Function.prototype.bind. bind ist eine Methode. Es wird auf Funktionsprototyp aufgerufen. Diese Methode erstellt eine Funktion, deren Hauptteil der Funktion ähnelt, für die sie aufgerufen wird. Das 'this' bezieht sich jedoch auf den ersten Parameter, der an die bind-Methode übergeben wird. Die Syntax lautet

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

Beispiel:--

  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;

Es macht im Grunde alles, was 'dies' innerhalb der Funktion ist, zu dem Objekt, das Sie übergeben, richtig?
Harvey Lin

11

Die Methode bind () erstellt eine neue Funktionsinstanz, deren Wert an den Wert gebunden ist, der an bind () übergeben wurde. Zum Beispiel:

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

Hier wird aus sayColor () eine neue Funktion namens objectSayColor () erstellt, indem bind () aufgerufen und das Objekt o übergeben wird. Die Funktion objectSayColor () hat einen Wert, der o entspricht. Wenn Sie die Funktion auch als globaler Aufruf aufrufen, wird die Zeichenfolge "blau" angezeigt.

Referenz: Nicholas C. Zakas - PROFESSIONAL JAVASCRIPT® FÜR WEBENTWICKLER


prägnantes und lakonisches Beispiel
Ahmad Sharif

9

Erstellen einer neuen Funktion durch Binden von Argumenten an Werte

Die bindMethode erstellt eine neue Funktion aus einer anderen Funktion mit einem oder mehreren Argumenten, die an bestimmte Werte gebunden sind, einschließlich des impliziten thisArguments.

Teilanwendung

Dies ist ein Beispiel für eine teilweise Anwendung . Normalerweise liefern wir eine Funktion mit all ihren Argumenten, die einen Wert ergibt. Dies wird als Funktionsanwendung bezeichnet. Wir wenden die Funktion auf ihre Argumente an.

Eine Funktion höherer Ordnung (HOF)

Die Teilanwendung ist ein Beispiel für eine Funktion höherer Ordnung (HOF), da sie eine neue Funktion mit weniger Argumenten ergibt.

Mehrere Argumente binden

Sie können bindFunktionen mit mehreren Argumenten in neue Funktionen umwandeln.

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

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

Konvertieren von der Instanzmethode in die statische Funktion

Im häufigsten Anwendungsfall erstellt die bindMethode beim Aufruf mit einem Argument eine neue Funktion, deren thisWert an einen bestimmten Wert gebunden ist. Tatsächlich wandelt dies eine Instanzmethode in eine statische Methode um.

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

Implementieren eines Stateful CallBack

Das folgende Beispiel zeigt, wie mithilfe der Bindung von thiseine Objektmethode als Rückruf fungieren kann, mit dem der Status eines Objekts problemlos aktualisiert werden kann.

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>


6

Wie bereits erwähnt, Function.bind()können Sie den Kontext angeben, in dem die Funktion ausgeführt wird (dh, Sie können übergeben, in welches Objekt das thisSchlüsselwort im Hauptteil der Funktion aufgelöst wird.

Einige analoge Toolkit-API-Methoden, die einen ähnlichen Dienst ausführen:

jQuery.proxy ()

Dojo.hitch ()


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

3

Betrachten Sie das unten aufgeführte einfache Programm.

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

2

Die Bindungsfunktion erstellt eine neue Funktion mit demselben Funktionskörper wie die aufgerufene Funktion. Sie wird mit diesem Argument aufgerufen. Warum verwenden wir Bindungsspaß? : Wenn jedes Mal, wenn eine neue Instanz erstellt wird und wir die erste Anfangsinstanz verwenden müssen, verwenden wir Bindungsspaß. Wir können den Bindungsspaß nicht überschreiben. Einfach speichert er das Anfangsobjekt der Klasse.

setInterval(this.animate_to.bind(this), 1000/this.difference);

0

Eine andere Verwendung besteht darin, dass Sie eine gebundene Funktion als Argument an eine andere Funktion übergeben können, die in einem anderen Ausführungskontext ausgeführt wird.

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

function somefunction(cb){
  //other code
  cb();
}
somefunction.call({}, cb);

0

Einfaches Beispiel

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

0

Bindungsmethode

Eine Bindungsimplementierung könnte ungefähr so ​​aussehen:

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

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

Die Bindungsfunktion kann eine beliebige Anzahl von Argumenten annehmen und eine neue Funktion zurückgeben .

Die neue Funktion ruft die ursprüngliche Funktion mit der JS- Function.prototype.applyMethode auf.
Die applyMethode verwendet das erste an die Zielfunktion übergebene Argument als Kontext ( this), und das zweite Array-Argument der applyMethode ist eine Kombination der übrigen Argumente der Zielfunktion, die mit den Argumenten übereinstimmen, die zum Aufrufen der Rückgabe verwendet werden Funktion (in dieser Reihenfolge).

Ein Beispiel kann ungefähr so ​​aussehen:

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


0

Einfache Erklärung:

bind () erstellt eine neue Funktion, eine neue Referenz auf eine Funktion, die an Sie zurückgegeben wird.

In Parameter nach diesem Schlüsselwort übergeben Sie den Parameter, den Sie vorkonfigurieren möchten. Eigentlich wird es nicht sofort ausgeführt, sondern bereitet sich nur auf die Ausführung vor.

Sie können so viele Parameter vorkonfigurieren, wie Sie möchten.

Einfaches Beispiel zum Verständnis von bind:

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

-1

bind ist eine Funktion, die im Java-Skript-Prototyp verfügbar ist, da der Name vermuten lässt, dass bind verwendet wird, um Ihren Funktionsaufruf an den Kontext zu binden, mit dem Sie sich beispielsweise befassen:

    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%' 

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.