¿Javascript call () y apply () vs bind ()?

794

Ya lo sé applyy callson funciones similares que establecen this(contexto de una función).

La diferencia está en la forma en que enviamos los argumentos (manual vs matriz)

Pregunta:

¿Pero cuándo debo usar el bind()método?

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
fuente
99
No es tu culpa si hay usuarios que miran los puntos de reputación del OP antes de publicar una respuesta o votar :) :)
Gabriel Llamas
54
llamar y aplicar llamar a una función mientras bind crea una función. Aunque concall()usted pasa argumentos individualmente yapply()como una matriz de argumentos. Para obtener más detalles, consulte la documentación vinculada que debería poder responder completamente a su pregunta.
No
3
kind of weird there is not an existing question about this :Con respecto a ese. Probablemente se deba a que bind()se agregó después de que los otros dos ya existían en JavaScript 1.8.5 - ECMA-262, 5a edición. Mientras call()y apply()han existido desde JavaScript 1.3 - ECMA-262 3rd Edition. SO tiene preguntas sobre ellos como: ¿cuál es la diferencia entre llamar y aplicar ? Sin embargo, solo estoy adivinando ya que me preguntaba eso.
No
¿Necesita estos métodos (llamar, aplicar, vincular) aquí? sin que esto también se puede llamar al método y esto va a apuntar a objetar solamente
Mahi
mira
techyaura

Respuestas:

131

Creé esta comparación entre objetos de función, llamadas de función call/applyy hace bindun tiempo:

ingrese la descripción de la imagen aquí

.bindle permite establecer el thisvalor ahora mientras le permite ejecutar la función en el futuro , ya que devuelve un nuevo objeto de función.

Felix Kling
fuente
779

Úselo .bind()cuando desee que esa función se llame más tarde con un determinado contexto, útil en eventos. Use .call()o .apply()cuando desee invocar la función inmediatamente y modifique el contexto.

Llamar / aplicar llama a la función de inmediato, mientras que binddevuelve una función que, cuando se ejecute más tarde, tendrá el contexto correcto establecido para llamar a la función original. De esta manera, puede mantener el contexto en devoluciones de llamada y eventos asíncronos.

Lo hago mucho:

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

Lo uso ampliamente en Node.js para devoluciones de llamada asíncronas para las que quiero pasar un método de miembro, pero todavía quiero que el contexto sea la instancia que inició la acción asíncrona.

Una implementación simple e ingenua de bind sería como:

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

Hay más (como pasar otros argumentos), pero puede leer más al respecto y ver la implementación real en el MDN .

Espero que esto ayude.

Chad
fuente
2
@RoyiNamir que es correcto, puede usar la función "enlazada" devuelta más tarde, y el contexto se mantendrá.
Chad
55
Eso es exactamente lo que bindvuelve.
Chad
@RoyiNamir Editó mi respuesta
Chad
44
También puede usar bind para parciales, pasando argumentos antes de que se llame a la función.
Andrew Kirkegaard
1
Solo estás reimplementando la vinculación, no hay realmente una diferencia. De cualquier manera, solo lo está envolviendo en un cierre que tiene acceso a una variable de alcance que contiene el contexto. Su código es básicamente el polyfill que publiqué.
Chad
446

Todos adjuntan esto a la función (u objeto) y la diferencia está en la invocación de la función (ver más abajo).

La llamada adjunta esto a la función y ejecuta la función inmediatamente:

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 asocia esto a la función y debe invocarse por separado de esta manera:

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"

o así:

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

apply es similar a call, excepto que toma un objeto tipo matriz en lugar de enumerar los argumentos uno por uno:

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"                                     
CuriosoSúperhéroe
fuente
1
¿Significa esto que la diferencia es que Bind es un cierre?
Gregory R.
Me acaba de enseñar sobre la característica de argumentos utilizada dentro de una función a través de su fragmento de código. Es recomendable mencionar "use strict"para evitar anular tales palabras clave reservadas. +1.
RBT
@Max estuvo de acuerdo; He enviado una edición en la que "esto" está mal o no tiene sentido hasta que usamos bind / call / apply
iono
1
Gracias por las sugerencias de mejora. Edité mi respuesta un poco. @iono Su sugerencia tenía algunas imprecisiones, por lo que no pude aprobarla, pero hice mis propias ediciones en la respuesta. Esperemos que ahora sea más completo.
CuriousSuperhero
200

Responda en forma SIMPLEST

  • Call invoca la función y le permite pasar argumentos uno por uno.
  • Aplicar invoca la función y le permite pasar argumentos como una matriz.
  • Bind devuelve una nueva función, que le permite pasar esta matriz y cualquier número de argumentos.

Ejemplos de aplicación vs. llamada vs. enlace

Llamada

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

Aplicar

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

Enlazar

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

Cuándo usar cada uno

Llamar y aplicar son bastante intercambiables. Simplemente decida si es más fácil enviar una matriz o una lista de argumentos separados por comas.

Siempre recuerdo cuál es cuál al recordar que Call es para coma (lista separada) y Apply es para Array.

Bind es un poco diferente. Devuelve una nueva función. Llamar y Aplicar ejecutan la función actual inmediatamente.

Bind es genial para muchas cosas. Podemos usarlo para curry funciones como en el ejemplo anterior. Podemos tomar una función hello simple y convertirla en helloJon o helloKelly. También podemos usarlo para eventos como onClick donde no sabemos cuándo serán despedidos, pero sabemos qué contexto queremos que tengan.

Referencia: codeplanet.io

Amit Shah
fuente
8
Impresionante respuesta, si fue mi pregunta, te doy la marca de verificación
AmerllicA
En cally apply, ¿se sigue que si no tienes un thismétodo dentro del método, entonces asignarías el primer argumento como a null?
Daryll Santos
1
@DaryllSantos, según MDN: thisArg Opcional. El valor de esto proporcionó la llamada a una función. Tenga en cuenta que este puede no ser el valor real visto por el método: si el método es una función en modo no estricto, nulo e indefinido se reemplazará con el objeto global y los valores primitivos se convertirán en objetos. Entonces, si no usa esto en la función, no importa.
Amit Shah
44
llamar = = coma, aplicar == matriz fue un pequeño truco de memorización
drlff
var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanFunciona perfectamente bien y produce VM128: 4 Hola Jon Kuperman
Pratik
53

Permite establecer el valor para thisindependiente de cómo se llama la función. Esto es muy útil cuando se trabaja con devoluciones de llamada:

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

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

Para lograr el mismo resultado con callse vería así:

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

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
jantimon
fuente
55
El uso de lo .bind()que has mostrado antes es incorrecto. Cuando use fn.bind(obj)otra función, se le devolverá (no es que haya creado antes). Y no hay habilidades para cambiar el valor del thisinterior de la bindedfunción. Principalmente esto se utiliza para el thisseguro de devolución de llamada . Pero en el tuyo, no hay diferencias en el resultado. Pero fn !== fn.bind(obj);ten en cuenta eso.
ValeriiVasin
@InviS No entiendo tu comentario, ¿por qué no hay diferencia?
jantimon
2
La diferencia en llamar y aplicar es. en call, pasa argumentos como cadenas separadas por comas, mientras que en apply puedes pasar argumentos en forma de matriz. el resto son lo mismo.
Ashish Yadav
cadenas separadas por comas ? solo pasa argumentos como separados por comas !!
Sudhansu Choudhary
46

Supongamos que tenemos multiplicationfunción

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

Vamos a crear algunas funciones estándar usando bind

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

Ahora multiby2 (b) es igual a multiplicación (2, b);

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

¿Qué pasa si paso ambos parámetros en bind?

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

Ahora getSixAlways () es igual a la multiplicación (3,2);

getSixAlways();//6

incluso pasar parámetro devuelve 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Esto crea una nueva función de multiplicación y la asigna a magicMultiplication.

Oh no, estamos ocultando la funcionalidad de multiplicación en magicMultiplication.

llamando magicMultiplicationdevuelve un espacio en blancofunction b()

en la ejecución funciona bien magicMultiplication(6,5); //30

¿Qué tal llamar y aplicar?

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

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

En palabras simples, bindcrea la función cally applyejecuta la función mientras applyespera los parámetros en la matriz

tk120404
fuente
Muy bien explicado!
CatalinBerta
3
+1 para "En palabras simples, bindcrea la función cally applyejecuta la función mientras applyespera los parámetros en la matriz"
Josh Buchea
32

Ambos Function.prototype.call()y Function.prototype.apply()llaman a una función con un thisvalor dado , y devuelven el valor de retorno de esa función.

Function.prototype.bind(), por otro lado, crea una nueva función con un thisvalor dado y devuelve esa función sin ejecutarla.

Entonces, tomemos una función que se vea así:

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

Ahora, tomemos un objeto que se vea así:

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

Podemos vincular nuestra función a nuestro objeto de esta manera:

Obj.log = logProp.bind(Obj);

Ahora, podemos ejecutar Obj.logen cualquier parte de nuestro código:

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

Donde realmente se pone interesante, es cuando no solo se vincula un valor para this, sino también para su argumento prop:

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

Ahora podemos hacer esto:

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

enlace : enlaza la función con el valor y el contexto proporcionados, pero no ejecuta la función. Para ejecutar la función, debe llamar a la función.

llamada : ejecuta la función con el contexto y el parámetro proporcionados.

apply : ejecuta la función con el contexto y el parámetro proporcionados como matriz .

Siddhartha
fuente
simple y humilde!
Habeeb Perwad
18

He aquí un buen artículo para ilustrar la diferencia entre bind(), apply()y call(), resumir de la siguiente manera.

  • bind()nos permite establecer fácilmente qué objeto específico estará vinculado a esto cuando se invoque una función o método.

    // 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() permítanos tomar prestados métodos

    // 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 problema con este ejemplo es que estamos agregando un nuevo método showDataen el carsobjeto y es posible que no queramos hacerlo solo para tomar prestado un método porque el objeto de los automóviles ya puede tener una propiedad o un nombre de método showData. No queremos sobrescribirlo accidentalmente. Como veremos en nuestra discusión sobre Applyy a Callcontinuación, es mejor tomar prestado un método usando el método Applyo Call.

  • bind() permítanos curry una función

    La función Curry , también conocida como aplicación de función parcial , es el uso de una función (que acepta uno o más argumentos) que devuelve una nueva función con algunos de los argumentos ya establecidos.

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

    Podemos usar bind()para curry esta greetfunción

    // 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()o call()para establecer este valor

    El apply, callybind los métodos se usan para establecer el valor de esta cuando se invoca un método, y lo hacen de manera ligeramente diferente para permitir el uso de control directo y la versatilidad de nuestro código JavaScript.

    Los métodos applyy callson casi idénticos al establecer este valor, excepto que pasa los parámetros de la función apply ()como una matriz , mientras que debe enumerar los parámetros individualmente para pasarlos al call ()método.

    Aquí hay un ejemplo para usar callo applyconfigurar esto en la función de devolución de llamada.

    // 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
  • Prestar funciones con applyocall

    • Métodos de préstamos de matriz

      Creemos un array-likeobjeto y tomemos prestados algunos métodos de matriz para operar en nuestro objeto tipo matriz.

      // 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​

      Otro caso común es que convertir argumentsa matriz de la siguiente manera

        // 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"]
    • Pedir prestado otros métodos

      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​
  • Se usa apply()para ejecutar la función de aridad variable

El Math.maxes un ejemplo de función de aridad variable,

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

Pero, ¿qué pasa si tenemos una serie de números para pasar Math.max? No podemos hacer esto:

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

Aquí es donde el apply ()método nos ayuda a ejecutar funciones variadas . En lugar de lo anterior, tenemos que pasar la matriz de números usando apply () así:

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
fuente
8

llamar / aplicar ejecuta la función inmediatamente:

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

bind no ejecuta la función inmediatamente, pero devuelve la función de aplicación ajustada (para su posterior ejecución):

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

Sintaxis

  • llamada (thisArg, arg1, arg2, ...)
  • aplicar (thisArg, argsArray)
  • bind (thisArg [, arg1 [, arg2 [, ...]]])

aquí

  • thisArg es el objeto
  • argArray es un objeto de matriz
  • arg1, arg2, arg3, ... son argumentos adicionales

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
fuente
6

La diferencia básica entre Call, Apply y Bind son:

Bind se usará si desea que su contexto de ejecución aparezca más adelante en la imagen.

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

Digamos que quiero usar este método en alguna otra variable

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

Para usar la referencia de coche en alguna otra variable, debe usar

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

Hablemos sobre el uso más extenso de la función de enlace

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

func();
// Number: 1

¿Por qué? Debido a que ahora func es bind con el Número 1, si no usamos bind en ese caso, apuntará a Global Object.

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

func();
// Object

Llamar, Aplicar se utilizan cuando desea ejecutar la declaración al mismo tiempo.

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
fuente
4

Llame aplicar y obligar. y cómo son diferentes.

Aprendamos a llamar y aplicar usando cualquier terminología diaria.

Tienes tres automóviles your_scooter , your_car and your_jetque comienzan con el mismo mecanismo (método). Creamos un objeto automobilecon un método 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");
    }
}

Vamos a entender cuándo se utiliza llamar y aplicar. Supongamos que usted es un ingeniero y lo tiene your_scooter, your_cary your_jetque no venía con un botón de arranque de botón y desea utilizar un tercero push_button_engineStart.

Si ejecuta las siguientes líneas de código, darán un error. ¿POR QUÉ?

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

Por lo tanto, el ejemplo anterior le da a your_scooter, your_car, your_jet una característica del objeto del automóvil.

Vamos a profundizar Aquí dividiremos la línea de código anterior. automobile.push_button_engineStartnos está ayudando a obtener el método utilizado.

Además, utilizamos apply o call utilizando la notación de puntos. automobile.push_button_engineStart.apply()

Ahora aplique y llame a aceptar dos parámetros.

  1. contexto
  2. argumentos

Así que aquí establecemos el contexto en la línea final de código.

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

La diferencia entre call y apply es solo que apply acepta parámetros en forma de matriz, mientras que call simplemente puede aceptar una lista de argumentos separados por comas.

¿Qué es la función JS Bind?

Una función de vinculación es básicamente la que vincula el contexto de algo y luego lo almacena en una variable para su ejecución en una etapa posterior.

Hagamos que nuestro ejemplo anterior sea aún mejor. Anteriormente utilizamos un método que pertenece al objeto del automóvil y lo utilizamos para equipar your_car, your_jet and your_scooter. Ahora imaginemos que queremos dar un separado por push_button_engineStartseparado para arrancar nuestros automóviles individualmente en cualquier etapa posterior de la ejecución que deseamos.

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

todavía no satisfecho?

Dejémoslo claro como lágrima. Hora de experimentar. Volveremos a llamar y aplicar la aplicación de función e intentaremos almacenar el valor de la función como referencia.

El siguiente experimento falla porque invocar y aplicar se invoca de inmediato, por lo tanto, nunca llegamos a la etapa de almacenar una referencia en una variable que es donde la función de vinculación roba el espectáculo

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

Sagar Munjal
fuente
3

Llamada: la llamada invoca la función y le permite pasar argumentos uno por uno

Aplicar: Aplicar invoca la función y le permite pasar argumentos como una matriz

Bind: Bind devuelve una nueva función, permitiéndole pasar esta matriz y cualquier número de argumentos.

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
fuente
2

call (): - Aquí pasamos los argumentos de la función individualmente, no en un formato de matriz

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 (): - Aquí pasamos los argumentos de la función en un formato de matriz

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

bind (): -

       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
fuente
2

Llamada de 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)

Aplicar JavaScript ()

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

** la función call y apply son llamadas de diferencia, toma un argumento separado pero aplica una matriz take como: [1,2,3] **

Enlace de JavaScript ()

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

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

Imagina, bind no está disponible. puedes construirlo fácilmente de la siguiente manera:

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

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

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

El concepto principal detrás de todos estos métodos es la excavación de funciones .

El préstamo de funciones nos permite usar los métodos de un objeto en un objeto diferente sin tener que hacer una copia de ese método y mantenerlo en dos lugares separados. Se logra mediante el uso de. llamada() , . aplicar (), o. bind (), todos los cuales existen para establecer explícitamente esto en el método que estamos tomando prestado

  1. Call invoca la función inmediatamente y le permite pasar argumentos uno por uno
  2. Aplicar invoca la función de inmediato y le permite pasar argumentos como una matriz .
  3. Bind devuelve una nueva función, y puede invocarla / llamarla en cualquier momento que desee invocando una función.

A continuación se muestra un ejemplo de todos estos métodos.

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

LLAMADA

el primer argumento, por ejemplo, el nombre dentro del método de llamada siempre es una referencia a (esta) variable y la última será variable de función

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

APLICAR

el método apply es el mismo que el método call, la única diferencia es que, los argumentos de la función se pasan en la lista de Array

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

ENLAZAR

el método de vinculación es igual a la llamada, excepto que, la vinculación devuelve una función que se puede usar más tarde invocando (no la llama de inmediato)

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

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

printMyNAme () es la función que invoca la función

a continuación se muestra el enlace para jsfiddle

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

Arham Chowdhury
fuente
-1

Creo que los mismos lugares son: todos pueden cambiar el valor de esta función. Las diferencias son: la función de enlace devolverá una nueva función como resultado; los métodos call y apply ejecutarán la función de inmediato, pero apply puede aceptar una matriz como params, y analizará la matriz por separado. Y también, la función de vinculación puede ser Curry.

Xin Tao
fuente
-3

la función de vinculación debe usarse cuando queremos asignar una función con un contexto particular para, por ejemplo,

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

en el ejemplo anterior si llamamos a la función demo.setValue () y pasamos la función this.getValue directamente, entonces no llama a la función demo.setValue directamente porque esto en setTimeout se refiere al objeto de ventana, por lo que debemos pasar el contexto del objeto de demostración a this.getValue función usando bind. significa que solo pasamos la función con el contexto del objeto de demostración que no llama realmente a la función.

Espero que entiendas .

para obtener más información, consulte la función de enlace de javascript saber en detalle

usuario7339156
fuente