Appel Javascript() & apply() vs bind()?
je sais déjà que apply
et call
sont des fonctions similaires qui mettent this
(contexte d'une fonction).
la différence réside dans la façon dont nous envoyons les arguments (manuel vs tableau)
Question:
mais quand devrais-je utiliser la méthode bind()
?
var obj = {
x: 81,
getX: function() {
return this.x;
}
};
alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));
16 réponses
utiliser .bind()
quand vous voulez que cette fonction soit appelée plus tard avec un certain contexte, utile dans les événements. Utilisez .call()
ou .apply()
lorsque vous voulez invoquer la fonction immédiatement et modifier le contexte.
l'Appel/s'appliquent appelez la fonction immédiatement, alors que les bind
retourne une fonction qui, lorsqu'elles sont exécutées, ont le bon cadre pour l'appel de la fonction d'origine. De cette façon, vous pouvez maintenir le contexte dans les callbacks async et événement.
je le fais beaucoup de choses:
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 callbacks async pour lesquels je veux passer une méthode member, mais je veux quand même que le contexte soit l'instance qui a démarré l'action async.
une mise en œuvre 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 (comme passer d'autres args), mais vous pouvez lire plus à ce sujet et voir la mise en œuvre réelle sur le MDN .
Espérons que cette aide.
ils attachent tous ce dans la fonction (ou l'objet) et la différence est dans la fonction invocation (voir ci-dessous).
appel attache ce en 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"
lier 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 ceci:
...
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc(); // output: Jim Smith says hello world"
appliquer est similaire à appel sauf qu'il prend un tableau comme objet plutôt que d'énumérer les arguments un à 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"
réponse sous la forme la plus simple
- Call invoque la fonction et vous permet de passer dans les arguments un par un.
- Appliquer appelle la fonction et vous permet de passer en arguments comme un tableau.
- Lier renvoie une nouvelle fonction, vous permettant de passer dans un ce tableau et n'importe quel nombre d'arguments.
Appliquer vs Call et Lier des Exemples
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 Chaque
sont assez interchangeables. Il suffit de décider 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 celui qui, en se rappelant que L'appel est pour la virgule (liste séparée) et S'applique est pour le tableau.
Bind est un peu différent. Il renvoie une nouvelle fonction. Appelez et appliquez exécutez la fonction courante immédiatement.
Bind est grand pour beaucoup de choses. Nous pouvons l'utiliser pour curry de fonctions comme dans l'exemple ci-dessus. Nous pouvons prendre une simple fonction hello et la transformer en un helloJon ou helloKelly. Nous pouvons également l'utiliser pour des événements comme onClick où nous ne savons pas quand ils vont être licenciés, mais nous savons ce contexte, nous voulons qu'ils ont.
Referance: codeplanet.io
Il permet de définir la valeur de this
indépendamment de la façon dont la fonction est appelée. Ceci est très utile pour travailler avec les callbacks:
function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(sayHello.bind(obj), 1000);
pour obtenir le même résultat avec call
ressemblerait à ceci:
function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(function(){sayHello.call(obj)}, 1000);
supposons que nous avons multiplication
fonction
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 égale à la multiplication(2,b);
multiby2(3); //6
multiby2(4); //8
Que faire si je passe les deux paramètres dans bind
var getSixAlways = multiplication.bind(this,3,2);
Maintenant getSixAlways() est égale à la multiplication(3,2);
getSixAlways();//6
même paramètre de passage renvoie 6;
getSixAlways(12); //6
var magicMultiplication = multiplication.bind(this);
cela crée une nouvelle fonction de multiplication et l'assigne à magicMultiplication.
Oh non, nous cache la multiplication des fonctionnalités dans magicMultiplication.
appel
magicMultiplication
renvoie un blanc function b()
sur l'exécution, il fonctionne très bien
magicMultiplication(6,5); //30
pourquoi pas call et de les appliquer?
magicMultiplication.call(this,3,2); //6
magicMultiplication.apply(this,[5,2]); //10
en termes simples, bind
crée la fonction, call
et apply
exécute la fonction tandis que apply
attend les paramètres dans le tableau
les deux Function.prototype.call()
et Function.prototype.apply()
appeler une fonction avec une valeur this
donnée, et retourner la valeur de retour de cette fonction.
Function.prototype.bind()
, d'un autre côté, crée une nouvelle fonction avec une valeur this
donnée, et retourne cette fonction sans l'exécuter.
donc, 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.log
n'importe où dans notre code:
Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10
où il devient vraiment intéressant, est quand vous non seulement liez 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 faire ceci:
Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
voici un bon article pour illustrer la différence entre bind()
, apply()
et call()
, résumez-le comme suit.
-
bind()
permet de définir facilement quel objet spécifique sera lié à ce 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
showData
sur l'objetcars
et nous pourrions ne pas vouloir faire cela juste pour emprunter une méthode parce que l'objet cars pourrait déjà avoir une propriété ou le nom de méthodeshowData
. Nous ne voulons pas de les effacer accidentellement. Comme nous le verrons dans notre discussion deApply
etCall
ci-dessous, il est préférable d'emprunter une méthode utilisant soit leApply
ouCall
méthode. -
bind()
nous permettre de curry une fonctionfonction Currying , également connu sous le nom de application partielle de fonction , est l'utilisation d'un 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()
greet
fonction// 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()
oucall()
pour définir ce valeurles méthodes
apply
,call
, etbind
sont toutes utilisées pour définir cette valeur lors de l'invocation d'une méthode, et ils le font dans légèrement différentes façons d'utiliser le contrôle direct et la polyvalence dans notre code JavaScript.le
apply
et Les méthodescall
sont presque identiques lorsque vous définissez cette valeur , sauf que vous passez les paramètres de fonction àapply ()
comme un tableau , alors que vous devez énumérer les paramètres individuellement pour les passer à la méthodecall ()
.voici un exemple pour utiliser
call
ouapply
pour définir 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
-
fonctions D'emprunt avec
apply
oucall
-
Emprunter les méthodes de Tableau
créons un objet
array-like
et empruntons quelques méthodes array pour opérer sur l'objet de type our array.// 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 celui de convertir
arguments
en 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 les méthodes de
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 variable-arité fonction
le Math.max
est un 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 si nous avions un tableau de nombres à passer à 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 ici que la méthode apply ()
nous aide à exécuter fonctions variadiques . Au lieu de ce qui précède, nous devons passer le tableau des 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
lier : Il lie la fonction avec la valeur et le contexte, mais il n'exécute la fonction. Pour exécuter la fonction, vous devez appeler la fonction.
appel : Il exécute la fonction avec le contexte et les paramètres.
apply : il exécute la fonction avec le contexte fourni et paramètre en tant que tableau .
appel exécute la fonction immédiatement:
func.call(context, arguments);
func.apply(context, [argument1,argument2,..]);
lier ne pas exécuter la fonction immédiatement, mais renvoie enveloppé appliquer de la fonction (pour exécution ultérieure):
function bind(func, context) {
return function() {
return func.apply(context, arguments);
};
}
- Appel appelle la fonction et vous permet de passer en arguments un par un.
- Apply invoque la fonction et vous permet de passer dans les arguments comme un tableau.
- Lier retourne une nouvelle fonction, vous permettant de passer dans ce tableau et un nombre quelconque d'arguments.
Appel s'appliquent et se lient. et comment ils sont différents.
permet d'apprendre à appeler et à appliquer en utilisant n'importe quelle terminologie quotidienne.
vous avez trois automobiles your_scooter , your_car and your_jet
qui commencent avec le même mécanisme (méthode).
Nous avons créé un objet automobile
avec 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 et l'application sont utilisés. Laisse supposer que vous êtes ingénieur et vous avez your_scooter
, your_car
et your_jet
qui n'est pas venu avec un push_button_engine_start et vous souhaitez 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_car, votre_jet une fonctionnalité de l'objet automobile.
Let's enfoncent de plus en plus
Ici, nous allons diviser le au-dessus de la ligne de code.
automobile.push_button_engineStart
nous aide à obtenir la méthode utilisée.
ensuite, nous utilisons appliquer ou appeler en utilisant la notation de point.
automobile.push_button_engineStart.apply()
maintenant appliquer et appeler accepter deux paramètres.
- contexte
- arguments
donc ici nous définissons le contexte dans la ligne finale du code.
automobile.push_button_engineStart.apply(your_scooter,[20])
différence entre call et apply est juste que apply accepte les paramètres sous la forme d'un tableau alors que call peut simplement accepter une liste d'arguments séparée par une virgule.
qu'est-ce que la fonction JS Bind?
une fonction bind est fondamentalement une fonction qui lie le contexte de quelque chose et le stocke ensuite dans une variable pour exécution à un stade ultérieur.
faisons notre exemple précédent encore mieux. Plus tôt, nous avons utilisé une méthode appartenant à l'objet de l'automobile et utilisé pour équiper your_car, your_jet and your_scooter
. Imaginons maintenant que nous voulions donner un push_button_engineStart
séparé pour démarrer nos automobiles individuellement à n'importe quelle étape ultérieure 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?
soyons clairs comme larme. Le temps d'expérimenter. Que nous réfractassions pour appeler et appliquer l'application de fonction et essayer de stocker la valeur de la fonction comme une référence.
l'expérience ci-dessous échoue parce que l'appel et l'application sont invoqués immédiatement, Donc, nous n'arrivons jamais au stade de stocker une référence dans une variable qui est où la fonction bind vole le spectacle
var test_function = automobile.push_button_engineStart.apply(your_scooter);
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
Imaginez, bind n'est pas disponible. vous pouvez facilement construire comme suit :
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;
je pense que les mêmes endroits d'entre eux sont: tous peuvent changer la cette valeur d'une fonction.Les différences sont les suivantes: la fonction bind renverra une nouvelle fonction en conséquence; les méthodes call et apply exécuteront la fonction immédiatement, mais apply peut accepter un tableau comme params,et il parsera le tableau séparé.Et aussi, la fonction de liaison peut être Nourrissage.
lier fonction doit être utilisée lorsque l'on veut attribuer une fonction à 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 de démonstration.setValue() de la fonction et de passer cette.la fonction getValue directement puis elle n'appelle pas demo.la fonction setValue directement parce que ceci dans setTimeout se réfère à l'objet window, nous devons donc passer le contexte de l'objet demo à celui-ci.fonction getValue utilisant bind. cela signifie que nous passons seulement la fonction avec le contexte de l'objet de démonstration pas actully l'appel de la fonction.
J'espère que vous comprenez .
pour de plus amples informations, veuillez consulter javascript fonction de liaison savoir dans le détail