Chamada Javascript () e apply () vs bind ()?

794

Eu já sei disso applye callsão funções semelhantes que definem this(contexto de uma função).

A diferença está na maneira como enviamos os argumentos (manual versus array)

Questão:

Mas quando devo usar o 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
fonte
9
Não é sua culpa se existem usuários que olhar para pontos de reputação do OP antes de postar uma resposta ou upvoting :)
Gabriel Llamas
54
chamar e aplicar chamar uma função enquanto bind cria uma função. Emboracall()você passe argumentos individualmente eapply()como uma matriz de argumentos. Para mais detalhes, consulte a documentação vinculada, que deve responder completamente à sua pergunta.
Não
3
kind of weird there is not an existing question about this :Quanto a isso. Provavelmente porque bind()foi adicionado depois que os outros dois já existiam no JavaScript 1.8.5 - ECMA-262, 5ª edição. Enquanto call()e apply()existem desde JavaScript 1.3 - ECMA-262 3rd Edition. O SO tem perguntas sobre eles, como: qual é a diferença entre ligar e aplicar . Eu só estou supondo que eu estava me perguntando isso.
Não,
você precisa desses métodos (chamar, aplicar, vincular) aqui? sem isso, você também pode chamar o método e isso apontará apenas para o objeto
Mahi
confira o link - techyaura-blogs.blogspot.com/2020/05/…
techyaura

Respostas:

131

Eu criei essa comparação entre objetos de função, chamadas de função call/applye bindum tempo atrás:

insira a descrição da imagem aqui

.bindpermite definir o thisvalor agora e executar a função no futuro , pois retorna um novo objeto de função.

Felix Kling
fonte
779

Use .bind()quando desejar que essa função seja chamada posteriormente com um determinado contexto, útil em eventos. Use .call()ou .apply()quando desejar chamar a função imediatamente e modifique o contexto.

Chamar / aplicar chama a função imediatamente, enquanto bindretorna uma função que, quando executada mais tarde, terá o contexto correto definido para chamar a função original. Dessa forma, você pode manter o contexto em retornos de chamada e eventos assíncronos.

Eu faço muito isso:

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

Eu o uso extensivamente no Node.js para retornos de chamada assíncronos para os quais desejo passar um método membro, mas ainda quero que o contexto seja a instância que iniciou a ação assíncrona.

Uma implementação simples e ingênua de bind seria como:

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

Há mais do que isso (como passar outros argumentos), mas você pode ler mais sobre isso e ver a implementação real no MDN .

Espero que isto ajude.

Chade
fonte
2
@RoyiNamir está correto, você pode usar a função "bound" retornada mais tarde, e o contexto será mantido.
Chad
5
É exatamente isso que bindretorna.
Chad
@RoyiNamir Editou minha resposta
Chad
4
Você também pode usar bind para parciais, passando argumentos antes que a função seja chamada.
Andrew Kirkegaard
1
Você está apenas reimplementando a ligação, não há realmente nenhuma diferença. De qualquer forma, você está envolto em um fechamento que tem acesso a uma variável de escopo que contém o contexto. Seu código é basicamente o polyfill que eu publiquei.
Chad
446

Todos eles anexam isso à função (ou objeto) e a diferença está na invocação da função (veja abaixo).

A chamada anexa isso à função e executa a função imediatamente:

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 anexa isso à função e precisa ser chamado separadamente assim:

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 assim:

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

apply é semelhante à chamada, exceto pelo fato de ser necessário um objeto de matriz em vez de listar os argumentos um de cada vez:

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"                                     
Super-herói
fonte
1
Isso significa que a diferença é que Bind é um fechamento?
Gregory R.
Você acabou de me ensinar sobre o recurso de argumentos usado dentro de uma função através do seu trecho de código. É recomendável mencionar "use strict"para evitar a substituição dessas palavras-chave reservadas. +1.
RBT
@ Max concordou; Eu enviei uma edição na qual "este" está errado ou não faz sentido até que utilizar o bind / call / aplicar
iono
1
Obrigado pelas sugestões de melhoria. Eu editei minha resposta um pouco. @iono Sua sugestão teve algumas imprecisões, portanto não foi possível aprová-la, mas fiz minhas próprias edições na resposta. Espero que agora seja mais abrangente.
CuriousSuperhero
200

Responda no formulário MAIS SIMPLES

  • Ligar chama a função e permite que você passe argumentos um por um.
  • Apply chama a função e permite transmitir argumentos como uma matriz.
  • Bind retorna uma nova função, permitindo que você passe nessa matriz e em qualquer número de argumentos.

Exemplos de Apply vs. Call vs. Bind

Ligar

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

Aplique

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

Ligar

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

Quando usar cada

Ligar e aplicar são bastante intercambiáveis. Apenas decida se é mais fácil enviar uma matriz ou uma lista de argumentos separados por vírgula.

Eu sempre lembro qual é qual, lembrando que Call é para vírgula (lista separada) e Apply é para Array.

Vincular é um pouco diferente. Retorna uma nova função. Call and Apply executa a função atual imediatamente.

O Bind é ótimo para muitas coisas. Podemos usá-lo para curry funções como no exemplo acima. Podemos pegar uma função simples de olá e transformá-la em um helloJon ou helloKelly. Também podemos usá-lo para eventos como onClick, onde não sabemos quando eles serão demitidos, mas sabemos em que contexto queremos que eles tenham.

Referência: codeplanet.io

Amit Shah
fonte
8
Resposta impressionante, se foi a minha pergunta, eu lhe dou uma marca.
precisa saber é o seguinte
Em calle apply, segue-se que, se você não tem um thisdentro do método, atribuiria o primeiro argumento como a null?
Daryll Santos
1
@DaryllSantos, de acordo com a MDN: thisArg opcional. O valor disso fornecido para a chamada para uma função. Observe que esse pode não ser o valor real visto pelo método: se o método for uma função no modo não estrito, nulo e indefinido serão substituídos pelo objeto global e os valores primitivos serão convertidos em objetos. Portanto, se você não usar isso na função, isso não importa.
Amit Shah
4
call = = vírgula, apply == array foi um pequeno truque de memorização
drlff
var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanFunciona perfeitamente bem e gera VM128: 4 Olá Jon Kuperman
Pratik
53

Permite definir o valor para thisindependente de como a função é chamada. Isso é muito útil ao trabalhar com retornos de chamada:

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

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

Para alcançar o mesmo resultado com, callficaria assim:

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

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
jantimon
fonte
5
O uso de .bind()como você mostrou antes está incorreto. Quando você usa fn.bind(obj)outra função, será retornado (não que você tenha criado antes). E não há habilidades para alterar o valor thisdentro da bindedfunção. Principalmente, isso é usado para o thisseguro de retorno de chamada . Mas no seu exemplo - não há diferenças no resultado. Mas fn !== fn.bind(obj);observe isso.
ValeriiVasin
@InviS Não entendo o seu comentário - por que não há nada diferente?
jantimon
2
A diferença entre ligar e aplicar é. na chamada, você passa argumentos como cadeias separadas por vírgula, enquanto na aplicação, você pode passar argumentos na forma de matriz. descanse o mesmo.
Ashish Yadav
cordas separadas por vírgula ?? basta passar argumentos como separados por vírgula !!
Sudhansu Choudhary
46

Assuma que temos multiplicationfunção

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

Vamos criar algumas funções padrão usando bind

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

Agora multiby2 (b) é igual à multiplicação (2, b);

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

E se eu passar os dois parâmetros no bind

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

Agora getSixAlways () é igual à multiplicação (3,2);

getSixAlways();//6

mesmo passando o parâmetro retorna 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Isso cria uma nova função de multiplicação e a atribui a magicMultiplication.

Ah, não, estamos escondendo a funcionalidade de multiplicação em magicMultiplication.

chamando magicMultiplicationretorna um espaço em brancofunction b()

na execução funciona bem magicMultiplication(6,5); //30

Que tal ligar e aplicar?

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

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

Em palavras simples, bindcria a função calle applyexecuta a função enquanto applyespera os parâmetros na matriz

tk120404
fonte
Muito bem explicado!
CatalinBerta
3
+1 para "Em palavras simples, bindcria a função calle applyexecuta a função enquanto applyespera os parâmetros na matriz"
Josh Buchea 8/17/17
32

Ambos Function.prototype.call()e Function.prototype.apply()chamam uma função com um determinado thisvalor e retornam o valor de retorno dessa função.

Function.prototype.bind(), por outro lado, cria uma nova função com um determinado thisvalor e retorna essa função sem executá-la.

Então, vamos assumir uma função que se parece com isso:

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

Agora, vamos pegar um objeto que se parece com isso:

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

Podemos vincular nossa função ao nosso objeto assim:

Obj.log = logProp.bind(Obj);

Agora, podemos executar Obj.logem qualquer lugar do nosso código:

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

O que realmente interessa é quando você não apenas vincula um valor para this, mas também para seu argumento prop:

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

Agora podemos fazer isso:

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

bind : liga a função com o valor e o contexto fornecidos, mas não executa a função. Para executar a função, você precisa chamar a função.

chamada : Executa a função com contexto e parâmetro fornecidos.

apply : Executa a função com o contexto e o parâmetro fornecidos como array .

Siddhartha
fonte
simples e humilde!
Habeeb Perwad
18

Aqui está um bom artigo para ilustrar a diferença entre bind(), apply()e call(), resumi-lo como abaixo.

  • bind()permite definir facilmente qual objeto específico será vinculado a isso quando uma função ou método é invocado.

    // 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() nos permitem emprestar 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​

    Um problema com este exemplo é que estamos adicionando um novo método showDataao carsobjeto e talvez não desejemos fazer isso apenas para emprestar um método, porque o objeto cars já pode ter um nome de propriedade ou método showData. Não queremos substituí-lo acidentalmente. Como veremos em nossa discussão sobre Applye Callabaixo, é melhor emprestar um método usando o método Applyou Call.

  • bind() nos permitem curry uma função

    A função Currying , também conhecida como aplicativo de função parcial , é o uso de uma função (que aceita um ou mais argumentos) que retorna uma nova função com alguns dos argumentos já definidos.

    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 greetfunção

    // 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()ou call()para definir esse valor

    A apply, callebind métodos são usados para definir a este valor ao chamar um método, e eles fazem isso de forma ligeiramente diferente para permitir o uso controle direto e versatilidade no nosso código JavaScript.

    Os métodos applye callsão quase idênticos ao definir esse valor, exceto que você passa os parâmetros da função apply ()como uma matriz , enquanto você precisa listar os parâmetros individualmente para passá-los ao call ()método.

    Aqui está um exemplo para usar callou applydefinir isso na função de retorno de chamada.

    // 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
  • Empréstimo funciona com applyoucall

    • Métodos de empréstimo de matriz

      Vamos criar um array-likeobjeto e emprestar alguns métodos de matriz para operar em nosso objeto semelhante a 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​

      Outro caso comum é que converter argumentsem array da seguinte maneira

        // 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"]
    • Emprestar outros 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​
  • Use apply()para executar a função de variável arity

Este Math.maxé um exemplo de função de variável aridade,

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

Mas e se tivermos uma matriz de números para transmitir Math.max? Não podemos fazer isso:

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

É aqui que o apply ()método nos ajuda a executar funções variadas . Em vez do acima, temos que passar a matriz de números usando apply () assim:

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

call / apply executa a função imediatamente:

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

bind não executa a função imediatamente, mas retorna a função Apply aplicada (para execução posterior):

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

Sintaxe

  • chamada (thisArg, arg1, arg2, ...)
  • apply (thisArg, argsArray)
  • bind (thisArg [, arg1 [, arg2 [, ...]]])

Aqui

  • thisArg é o objeto
  • argArray é um objeto de matriz
  • arg1, arg2, arg3, ... são argumentos adicionais

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

A diferença básica entre Chamar, Aplicar e Vincular são:

A ligação será usada se você desejar que seu contexto de execução seja exibido mais adiante na figura.

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 eu queira usar esse método em alguma outra variável

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

Para usar a referência de carro em alguma outra variável, você deve usar

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

Vamos falar sobre o uso mais extenso da função de ligação

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

func();
// Number: 1

Por quê? Como agora func é bind com o número 1, se não usarmos bind nesse caso, ele apontará para Objeto Global.

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

func();
// Object

Chamar, Aplicar são usados ​​quando você deseja executar a instrução ao mesmo tempo.

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

Ligue para aplicar e vincular. e como eles são diferentes.

Vamos aprender a ligar e aplicar usando qualquer terminologia diária.

Você tem três automóveis your_scooter , your_car and your_jetque começam com o mesmo mecanismo (método). Nós criamos um objeto automobilecom um 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 entender quando é chamada e aplicar usado. Suponhamos que você seja um engenheiro e tenha your_scooter, your_care your_jetque não veio com um push_button_engine_start, e que deseja usar um terceiro push_button_engineStart.

Se você executar as seguintes linhas de código, elas darão um erro. PORQUE?

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

Portanto, o exemplo acima fornece com êxito o seu_scooter, seu_carro, seu_jato, um recurso do objeto automóvel.

Vamos nos aprofundar Aqui vamos dividir a linha de código acima. automobile.push_button_engineStartestá nos ajudando a obter o método que está sendo usado.

Além disso, usamos apply ou call usando a notação de ponto. automobile.push_button_engineStart.apply()

Agora aplique e chame aceitar dois parâmetros.

  1. contexto
  2. argumentos

Então, aqui configuramos o contexto na linha final do código.

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

A diferença entre call e apply é apenas o apply que aceita parâmetros na forma de uma matriz, enquanto a chamada simplesmente pode aceitar uma lista de argumentos separados por vírgula.

o que é a função JS Bind?

Uma função de ligação é basicamente o que liga o contexto de algo e, em seguida, armazena-o em uma variável para execução posteriormente.

Vamos melhorar ainda mais o nosso exemplo anterior. Anteriormente, usamos um método pertencente ao objeto automóvel e o equipamos your_car, your_jet and your_scooter. Agora vamos imaginar que queremos dar um separado push_button_engineStartseparadamente para iniciar nossos automóveis individualmente em qualquer estágio posterior da execução que desejamos.

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

ainda não está satisfeito?

Vamos deixar claro como uma lágrima. Hora de experimentar. Voltaremos a chamar e aplicar o aplicativo de funções e tentar armazenar o valor da função como referência.

A experiência abaixo falha porque call e apply são invocados imediatamente; portanto, nunca chegamos ao estágio de armazenar uma referência em uma variável que é onde a função bind rouba o show

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

Sagar Munjal
fonte
3

Call: call chama a função e permite que você passe argumentos um por um

Apply: Apply chama a função e permite que você passe argumentos como uma matriz

Vincular: Vincular retorna uma nova função, permitindo que você transmita essa matriz e qualquer 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
fonte
2

call (): - Aqui passamos os argumentos da função individualmente, não em um 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 (): - Aqui passamos os argumentos da função em um 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)); 

ligar() :--

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

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

** a função call e apply é chamada de diferença, usa um argumento separado, mas aplica um array como: [1,2,3]

JavaScript bind ()

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

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

Imagine, o bind não está disponível. você pode construí-lo facilmente da seguinte maneira:

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

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

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

O principal conceito por trás de todos esses métodos é a função Burrowing .

O empréstimo de funções nos permite usar os métodos de um objeto em um objeto diferente sem precisar fazer uma cópia desse método e mantê-lo em dois locais separados. É realizado através do uso de. ligar() , . apply () ou. bind (), todos os quais existem para definir explicitamente isso no método que estamos emprestando

  1. A chamada chama a função imediatamente e permite que você passe argumentos um por um
  2. Apply chama a função imediatamente e permite transmitir argumentos como uma matriz .
  3. Bind retorna uma nova função, e você pode invocá-la / chamá-la sempre que quiser, invocando uma função.

Abaixo está um exemplo de todos esses métodos

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

LIGAR

o primeiro argumento, por exemplo, nome dentro do método de chamada, é sempre uma referência a (this) variável e, posteriormente, será variável de função

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

APLIQUE

O método apply é o mesmo que o método call, o único diff é que, os argumentos da função são passados ​​na lista Array

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

LIGAR

O método bind é o mesmo que call, exceto que, o bind retorna uma função que pode ser usada posteriormente chamando-o (não o chama imediatamente)

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

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

printMyNAme () é a função que chama a função

abaixo está o link para jsfiddle

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

Arham Chowdhury
fonte
-1

Eu acho que os mesmos lugares deles são: todos eles podem alterar o valor de uma função. As diferenças deles são: a função bind retornará uma nova função como resultado; os métodos de chamada e aplicação executam a função imediatamente, mas a aplicação pode aceitar uma matriz como parâmetros e analisará a matriz separada. Além disso, a função de ligação pode ser Currying.

Xin Tao
fonte
-3

A função bind deve ser usada quando queremos atribuir uma função com contexto específico, por exemplo.

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

no exemplo acima, se chamarmos a função demo.setValue () e passarmos a função this.getValue diretamente, ela não chamará a função demo.setValue diretamente porque isso em setTimeout se refere ao objeto de janela, portanto, precisamos passar o contexto do objeto de demonstração para this.getValue função usando bind. significa que apenas passamos a função com o contexto do objeto de demonstração e não chamamos a função de verdade.

Espero que você entenda .

Para obter mais informações, consulte a função de ligação do javascript.

user7339156
fonte