Ich weiß bereits, dass apply
und call
ähnliche Funktionen sind, die this
(Kontext einer Funktion) setzen.
Der Unterschied liegt in der Art und Weise, wie wir die Argumente senden (manuell vs. Array).
Frage:
Aber wann sollte ich die bind()
-Methode verwenden?
var obj = {
x: 81,
getX: function() {
return this.x;
}
};
alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));
Verwenden Sie .bind()
, wenn Sie möchten, dass diese Funktion später mit einem bestimmten Kontext aufgerufen wird, der für Ereignisse nützlich ist. Verwenden Sie .call()
oder .apply()
, wenn Sie die Funktion sofort aufrufen möchten, und ändern Sie den Kontext.
Call/apply Ruft die Funktion sofort auf, während bind
eine Funktion zurückgibt, bei deren Ausführung später der richtige Kontext für den Aufruf der ursprünglichen Funktion festgelegt wird. Auf diese Weise können Sie den Kontext in asynchronen Rückrufen und Ereignissen beibehalten.
Ich mache das oft:
function MyObject(element) {
this.Elm = element;
element.addEventListener('click', this.onClick.bind(this), false);
};
MyObject.prototype.onClick = function(e) {
var t=this; //do something with [t]...
//without bind the context of this function wouldn't be a MyObject
//instance as you would normally expect.
};
Ich verwende es in Node.js ausgiebig für asynchrone Callbacks, für die ich eine Member-Methode übergeben möchte, möchte aber trotzdem, dass der Kontext die Instanz ist, die die async-Aktion gestartet hat.
Eine einfache, naive Implementierung von bind würde folgendermaßen aussehen:
Function.prototype.bind = function(ctx) {
var fn = this;
return function() {
fn.apply(ctx, arguments);
};
};
Es gibt mehr dazu (wie das Übergeben anderer Argumente), aber Sie können mehr darüber lesen und die tatsächliche Implementierung auf dem MDN sehen.
Hoffe das hilft.
Sie alle fügenthisin Funktion (oder Objekt) ein, und der Unterschied liegt im Funktionsaufruf (siehe unten).
call attachesthisinto function und führt die Funktion sofort aus:
var person = {
name: "James Smith",
hello: function(thing) {
console.log(this.name + " says hello " + thing);
}
}
person.hello("world"); // output: "James Smith says hello world"
person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"
bind attachesthisin die Funktion und muss separat wie folgt aufgerufen werden:
var person = {
name: "James Smith",
hello: function(thing) {
console.log(this.name + " says hello " + thing);
}
}
person.hello("world"); // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world"); // output: Jim Smith says hello world"
oder so:
...
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc(); // output: Jim Smith says hello world"
apply ist ähnlich wie call , außer dass ein Array-ähnliches Objekt verwendet wird, anstatt die Argumente einzeln aufzuführen:
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"
Antworten Sie in SIMPLEST-Formular
Anruf
var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};
function say(greeting) {
console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
say.call(person1, 'Hello'); // Hello Jon Kuperman
say.call(person2, 'Hello'); // Hello Kelly King
Sich bewerben
var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};
function say(greeting) {
console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
say.apply(person1, ['Hello']); // Hello Jon Kuperman
say.apply(person2, ['Hello']); // Hello Kelly King
Binden
var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};
function say() {
console.log('Hello ' + this.firstName + ' ' + this.lastName);
}
var sayHelloJon = say.bind(person1);
var sayHelloKelly = say.bind(person2);
sayHelloJon(); // Hello Jon Kuperman
sayHelloKelly(); // Hello Kelly King
Anrufen und bewerben sind ziemlich austauschbar. Entscheiden Sie sich einfach, ob es einfacher ist, ein Array oder eine durch Kommas getrennte Liste von Argumenten zu senden.
Ich erinnere mich immer an die welche, indem ich daran denke, dass Call für Komma (getrennte Liste) und Apply für Array steht.
Bind ist ein bisschen anders. Es wird eine neue Funktion zurückgegeben. Call and Apply führt die aktuelle Funktion sofort aus.
Bind ist für viele Dinge großartig. Wir können es verwenden, um Funktionen wie im obigen Beispiel zu curryieren. Wir können eine einfache Hallo-Funktion annehmen und daraus ein HalloJon oder HalloKelly machen. Wir können es auch für Events wie onClick verwenden, bei denen wir nicht wissen, wann sie ausgelöst werden, aber wir wissen, welchen Kontext wir haben sollen.
Referance: codeplanet.io
Es erlaubt, den Wert für this
unabhängig von der Funktionsweise der Funktion festzulegen. Dies ist sehr nützlich, wenn Sie mit Rückrufen arbeiten:
function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(sayHello.bind(obj), 1000);
Um dasselbe Ergebnis mit call
zu erzielen, würde es so aussehen:
function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(function(){sayHello.call(obj)}, 1000);
Angenommen, wir haben die Funktion multiplication
function multiplication(a,b){
console.log(a*b);
}
Erstellen wir einige Standardfunktionen mit bind
var multiby2 = multiplication.bind(this,2);
Jetzt ist multiby2 (b) gleich der Multiplikation (2, b);
multiby2(3); //6
multiby2(4); //8
Was ist, wenn ich beide Parameter in bind übergebe?
var getSixAlways = multiplication.bind(this,3,2);
Jetzt ist getSixAlways () gleich multiplication (3,2);
getSixAlways();//6
wenn der Parameter gerade übergeben wird, wird 6 zurückgegeben. getSixAlways(12); //6
var magicMultiplication = multiplication.bind(this);
Dadurch wird eine neue Multiplikationsfunktion erstellt und magicMultiplication zugewiesen.
Oh nein, wir verstecken die Multiplikationsfunktionalität in magicMultiplication.
aufrufen von magicMultiplication
gibt ein leeres function b()
zurück
bei der Ausführung funktioniert es gut magicMultiplication(6,5); //30
Wie wäre es anrufen und bewerben?
magicMultiplication.call(this,3,2); //6
magicMultiplication.apply(this,[5,2]); //10
Mit einfachen Worten, bind
erstellt die Funktion, call
und apply
führt die Funktion aus, während apply
die Parameter im Array erwartet
Beide Function.prototype.call()
und Function.prototype.apply()
rufen eine Funktion mit einem bestimmten this
-Wert auf und geben den Rückgabewert dieser Funktion zurück.
Function.prototype.bind()
erstellt dagegen eine neue Funktion mit einem bestimmten this
-Wert und gibt diese Funktion zurück, ohne sie auszuführen.
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);
Nun können wir Obj.log
überall in unserem Code ausführen:
Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10
Wo es wirklich interessant wird, ist, wenn Sie nicht nur einen Wert für this
binden, sondern auch für sein Argument prop
:
Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');
Wir können das jetzt tun:
Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
bind : Bindet die Funktion mit dem angegebenen Wert und Kontext, führt die Funktion jedoch nicht aus. Um die Funktion auszuführen, müssen Sie die Funktion aufrufen.
call : Er führt die Funktion mit dem angegebenen Kontext und Parametern aus.
apply : Es führt die Funktion mit dem angegebenen Kontext und dem Parameter als Array aus.
Hier ist ein guter Artikel , um den Unterschied zwischen bind()
, apply()
und call()
zu veranschaulichen. Fassen Sie ihn wie folgt zusammen.
Mit bind()
können Sie einfach festlegen, welches Objekt an this gebunden wird, 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 auszuleihen
// Here we have a cars object that does not have a method to print its data to the console
var cars = {
data:[
{name:"Honda Accord", age:14},
{name:"Tesla Model S", age:2}
]
}
// We can borrow the showData () method from the user object we defined in the last example.
// Here we bind the user.showData method to the cars object we just created.
cars.showData = user.showData.bind (cars);
cars.showData (); // Honda Accord 14
Ein Problem bei diesem Beispiel ist, dass wir eine neue Methode showData
für das cars
-Objekt und .__ hinzufügen. Wir möchten das nicht, um eine Methode auszuleihen, da das cars-Objekt bereits einen Eigenschafts- oder Methodennamen showData
..__ hat. Wir wollen es nicht versehentlich überschreiben. Wie wir in unserer Diskussion über Apply
und Call
unten sehen werden, ist es am besten, eine Methode mit der Apply
- oder Call
-Methode auszuleihen.
bind()
erlaubt uns, eine Funktion zu erstellen
Function Currying , auch bekannt als Teilfunktionsanwendung, ist die Verwendung einer .__-Funktion (die ein oder mehrere Argumente akzeptiert), die eine neue Funktion mit einigen der zurückgibt Argumente bereits gesetzt.
function greet (gender, age, name) {
// if a male, use Mr., else use Ms.
var salutation = gender === "male" ? "Mr. " : "Ms. ";
if (age > 25) {
return "Hello, " + salutation + name + ".";
}else {
return "Hey, " + name + ".";
}
}
Wir können bind()
verwenden, um diese greet
-Funktion zu erstellen
// So we are passing null because we are not using the "this" keyword in our greet function.
var greetAnAdultMale = greet.bind (null, "male", 45);
greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."
var greetAYoungster = greet.bind (null, "", 16);
greetAYoungster ("Alex"); // "Hey, Alex."
greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
apply()
oder call()
, um diesen Wert festzulegen
Die Methoden apply
, call
und bind
werden alle verwendet, um diesen Wert beim Aufrufen einer Methode festzulegen. Sie haben unterschiedliche Möglichkeiten, um die direkte Steuerung und Vielseitigkeit in unserem JavaScript-Code zuzulassen.
Die apply
- und call
-Methoden sind beim Festlegen dieses Wertes fast identisch, außer dass Sie die Funktionsparameter als ein Array an apply ()
übergeben, während Sie die Parameter einzeln auflisten müssen, um sie an die call ()
-Methode zu übergeben.
Hier ein Beispiel, in dem Sie call
oder apply
verwenden, um this in der Rückruffunktion festzulegen.
// Define an object with some properties and a method
// We will later pass the method as a callback function to another function
var clientData = {
id: 094545,
fullName: "Not Set",
// setUserName is a method on the clientData object
setUserName: function (firstName, lastName) {
// this refers to the fullName property in this object
this.fullName = firstName + " " + lastName;
}
};
function getUserInput (firstName, lastName, callback, callbackObj) {
// The use of the Apply method below will set the "this" value to callbackObj
callback.apply (callbackObj, [firstName, lastName]);
}
// The clientData object will be used by the Apply method to set the "this" value
getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
// the fullName property on the clientData was correctly set
console.log (clientData.fullName); // Barack Obama
Funktionen mit apply
oder call
ausleihen
Leihen Sie Array-Methoden
Erstellen wir ein array-like
-Objekt und leihen wir uns einige Array-Methoden aus, um das Array-ähnliche Objekt zu bearbeiten.
// An array-like object: note the non-negative integers used as keys
var anArrayLikeObj = {0:"Martin", 1:78, 2:67, 3:["Letta", "Marieta", "Pauline"], length:4 };
// Make a quick copy and save the results in a real array:
// First parameter sets the "this" value
var newArray = Array.prototype.slice.call (anArrayLikeObj, 0);
console.log (newArray); // ["Martin", 78, 67, Array[3]]
// Search for "Martin" in the array-like object
console.log (Array.prototype.indexOf.call (anArrayLikeObj, "Martin") === -1 ? false : true); // true
Ein weiterer häufiger Fall ist das Konvertieren von arguments
in 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
Verwenden Sie apply()
, um die Funktion variable-arity auszuführen
Math.max
ist ein Beispiel für die Variable-Arity-Funktion.
// We can pass any number of arguments to the Math.max () method
console.log (Math.max (23, 11, 34, 56)); // 56
Was aber, wenn wir eine Reihe von Zahlen haben, die an Math.max
übergeben werden sollen? Wir können das nicht machen:
var allNumbers = [23, 11, 34, 56];
// We cannot pass an array of numbers to the the Math.max method like this
console.log (Math.max (allNumbers)); // NaN
Hier hilft uns die apply ()
-Methode, Variadic-Funktionen auszuführen. Anstelle des Vorstehenden müssen wir das Zahlenfeld mit apply (
) übergeben, also:
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
call/apply führt die Funktion sofort aus:
func.call(context, arguments);
func.apply(context, [argument1,argument2,..]);
bind führt die Funktion nicht sofort aus, sondern gibt die umschlossene Funktion apply zurück (zur späteren Ausführung)
function bind(func, context) {
return function() {
return func.apply(context, arguments);
};
}
Aufruf anwenden und binden. Und wie sie sich unterscheiden.
Lernen Sie das Anrufen und Anwenden mit einer beliebigen täglichen Terminologie.
Sie haben drei Automobile your_scooter , your_car and your_jet
, Die mit dem gleichen Mechanismus (Methode) starten. Wir haben ein Objekt automobile
mit einer Methode Push_button_engineStart
Erstellt.
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");
}
}
Lass uns verstehen wann angerufen und angewendet wird. Nehmen wir an, Sie sind Ingenieur und haben your_scooter
, your_car
Und your_jet
, Die nicht mit einem Push_button_engine_start geliefert wurden, und Sie möchten einen Drittanbieter Push_button_engineStart
.
Wenn Sie die folgenden Codezeilen ausführen, wird ein Fehler ausgegeben. WARUM?
//your_scooter.Push_button_engineStart();
//your_car.Push_button_engineStart();
//your_jet.Push_button_engineStart();
automobile.Push_button_engineStart.apply(your_scooter,[20]);
automobile.Push_button_engineStart.call(your_jet,10);
automobile.Push_button_engineStart.call(your_car,40);
Das obige Beispiel verleiht Ihrem_Roller, Ihrem_Auto und Ihrem_Jet erfolgreich ein Merkmal aus einem Automobilobjekt.
Tauchen wir tiefer ein Hier teilen wir die obige Codezeile auf. automobile.Push_button_engineStart
Hilft uns dabei, die Methode zum Einsatz zu bringen.
Weiterhin verwenden wir Apply oder Call unter Verwendung der Punktnotation. automobile.Push_button_engineStart.apply()
Wenden Sie nun zwei Parameter an und rufen Sie sie auf.
Hier stellen wir also den Kontext in der letzten Codezeile ein.
automobile.Push_button_engineStart.apply(your_scooter,[20])
nterschied zwischen call und apply ist nur, dass apply Parameter in Form eines Arrays akzeptiert, während call einfach eine durch Kommas getrennte Liste von Argumenten akzeptieren kann.
Was ist die JS Bind-Funktion?
Eine Bindefunktion ist im Grunde genommen, die den Kontext von etwas bindet und ihn dann zur späteren Ausführung in einer Variablen speichert.
Machen wir unser vorheriges Beispiel noch besser. Früher verwendeten wir eine Methode, die zum Automobilobjekt gehört, und verwendeten sie zum Ausrüsten von your_car, your_jet and your_scooter
. Stellen wir uns nun vor, wir möchten einen separaten Push_button_engineStart
Vergeben, um unsere Automobile zu einem späteren Zeitpunkt der von uns gewünschten Ausführung einzeln zu starten.
var scooty_engineStart = automobile.Push_button_engineStart.bind(your_scooter);
var car_engineStart = automobile.Push_button_engineStart.bind(your_car);
var jet_engineStart = automobile.Push_button_engineStart.bind(your_jet);
setTimeout(scooty_engineStart,5000,30);
setTimeout(car_engineStart,10000,40);
setTimeout(jet_engineStart,15000,5);
immer noch nicht zufrieden?
Machen wir es klar als Träne. Zeit zum Experimentieren. Wir werden zurückgehen, um die Funktionsanwendung aufzurufen und anzuwenden, und versuchen, den Wert der Funktion als Referenz zu speichern.
Das folgende Experiment schlägt fehl, da call und apply sofort aufgerufen werden. Daher gelangen wir nie zum Stadium des Speicherns einer Referenz in einer Variablen, in der die Bindefunktion die Show stiehlt
var test_function = automobile.Push_button_engineStart.apply(your_scooter);
Der grundlegende Unterschied zwischen Call, Apply und Bind ist:
Bind wird verwendet, wenn der Ausführungskontext später im Bild angezeigt werden soll.
Ex:
var car = {
registrationNumber: "007",
brand: "Mercedes",
displayDetails: function(ownerName){
console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
}
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**
Angenommen, ich möchte diese Methode in einer anderen Variablen verwenden
var car1 = car.displayDetails('Nishant');
car1(); // undefined
Um die Referenz von car in einer anderen Variablen zu verwenden, sollten Sie verwenden
var car1 = car.displayDetails.bind(car, 'Nishant');
car1(); // Nishant this is your car 007 Mercedes
Lassen Sie uns über eine umfassendere Verwendung der Bindefunktion sprechen
var func = function() {
console.log(this)
}.bind(1);
func();
// Number: 1
Warum? Da func jetzt an Nummer 1 gebunden ist, zeigt es auf Global Object, wenn wir in diesem Fall keine Bindung verwenden.
var func = function() {
console.log(this)
}.bind({});
func();
// Object
Call, Apply werden verwendet, wenn Sie die Anweisung gleichzeitig ausführen möchten.
var Name = {
work: "SSE",
age: "25"
}
function displayDetails(ownerName) {
console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE
In apply we pass the array
displayDetails.call(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE
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
Call: call ruft die Funktion auf und ermöglicht es Ihnen, Argumente einzeln zu übergeben
Apply: Apply ruft die Funktion auf und ermöglicht das Übergeben von Argumenten als Array
Bind: Bind gibt eine neue Funktion zurück, mit der Sie dieses Array und eine beliebige Anzahl von Argumenten übergeben können.
var person1 = {firstName: 'Raju', lastName: 'king'};
var person2 = {firstName: 'chandu', lastName: 'shekar'};
function greet(greeting) {
console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
function greet2(greeting) {
console.log( 'Hello ' + this.firstName + ' ' + this.lastName);
}
greet.call(person1, 'Hello'); // Hello Raju king
greet.call(person2, 'Hello'); // Hello chandu shekar
greet.apply(person1, ['Hello']); // Hello Raju king
greet.apply(person2, ['Hello']); // Hello chandu shekar
var greetRaju = greet2.bind(person1);
var greetChandu = greet2.bind(person2);
greetRaju(); // Hello Raju king
greetChandu(); // Hello chandu shekar
Stellen Sie sich vor, Bind ist nicht verfügbar. Sie können es einfach wie folgt konstruieren:
var someFunction=...
var objToBind=....
var bindHelper = function (someFunction, objToBind) {
return function() {
someFunction.apply( objToBind, arguments );
};
}
bindHelper(arguments);
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;