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


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

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.


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.


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"                                     

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


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

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


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

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 .


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

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

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


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

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


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


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

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

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

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;

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


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


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.