JavaScript call () i Apply () vs bind ()?

794

Wiem już o tym applyi callustawiam podobne funkcje this(kontekst funkcji).

Różnica polega na sposobie, w jaki wysyłamy argumenty (ręczne vs tablica)

Pytanie:

Ale kiedy powinienem użyć tej bind()metody?

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
źródło
9
To nie twoja wina, że ​​są użytkownicy, którzy patrzą na punkty reputacji OP przed opublikowaniem odpowiedzi lub poprawką :)
Gabriel Llamas
54
Wywołaj i zastosuj Wywołaj funkcję, podczas gdy powiązanie tworzy funkcję. Chociaż wraz zcall()tobą przekazujesz argumenty indywidualnie iapply()jako tablicę argumentów. Aby uzyskać więcej informacji, zapoznaj się z dołączoną dokumentacją, która powinna być w stanie w pełni odpowiedzieć na twoje pytanie.
Nie,
3
kind of weird there is not an existing question about this :Co do tego. Jest tak prawdopodobnie dlatego, że bind()został dodany po tym, jak pozostałe dwa już istniały w JavaScript 1.8.5 - ECMA-262, 5. edycja. Podczas gdy call()i apply()istnieją już od JavaScript 1.3 - ECMA-262 3. wydanie. SO ma takie pytania, jak: jaka jest różnica między połączeniem a zastosowaniem . Zgaduję tylko, bo sam się nad tym zastanawiałem.
Nie,
czy potrzebujesz tych metod (zadzwoń, zastosuj, powiąż) tutaj? bez tego można również wywołać metodę, a to wskaże tylko na obiekt
Mahi
sprawdź
techyaura

Odpowiedzi:

131

Stworzyłem to porównanie między obiektami funkcji, wywołaniami funkcji call/applyi bindjakiś czas temu:

wprowadź opis zdjęcia tutaj

.bindpozwala ustawić thiswartość teraz, jednocześnie umożliwiając wykonanie funkcji w przyszłości , ponieważ zwraca nowy obiekt funkcji.

Felix Kling
źródło
779

Użyj, .bind()gdy chcesz, aby ta funkcja była później wywoływana w określonym kontekście, przydatnym w zdarzeniach. Użyj .call()lub, .apply()jeśli chcesz natychmiast wywołać funkcję i zmodyfikować kontekst.

Wywołaj / zastosuj natychmiast wywołaj funkcję, a bindzwróci funkcję, która, jeśli zostanie wykonana później, będzie miała ustawiony prawidłowy kontekst do wywołania oryginalnej funkcji. W ten sposób możesz zachować kontekst w asynchronicznych wywołaniach zwrotnych i zdarzeniach.

Często to robię:

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

Używam go szeroko w Node.js do wywołań zwrotnych asynchronicznych, dla których chcę przekazać metodę członka, ale nadal chcę, aby kontekstem była instancja, która rozpoczęła akcję asynchroniczną.

Prosta, naiwna implementacja wiązania wyglądałaby następująco:

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

Jest więcej w tym (jak przekazywanie innych argumentów), ale możesz przeczytać o tym więcej i zobaczyć prawdziwą implementację w MDN .

Mam nadzieję że to pomoże.

Czad
źródło
2
@RoyiNamir, który jest poprawny, możesz później użyć zwróconej funkcji „związany”, a kontekst zostanie zachowany.
Czad
5
Właśnie to bindpowraca.
Czad
@RoyiNamir Edytowałem moją odpowiedź
Czad
4
Możesz także użyć wiązania do częściowych, przekazując argumenty przed wywołaniem funkcji.
Andrew Kirkegaard
1
Po prostu reimplementujesz bind, tak naprawdę nie ma różnicy. Tak czy inaczej po prostu zawijasz go w zamknięcie, które ma dostęp do zmiennej zasięgu, która przechowuje kontekst. Twój kod jest w zasadzie polifillem, który opublikowałem.
Czad
446

Wszystkie dołączają to do funkcji (lub obiektu), a różnica polega na wywołaniu funkcji (patrz poniżej).

call dołącza to do funkcji i natychmiast wykonuje funkcję:

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 dołącza to do funkcji i musi być wywoływane osobno w następujący sposób:

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"

lub tak:

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

Zastosuj jest podobny do wywołania, z tym wyjątkiem, że pobiera obiekt podobny do tablicy, zamiast wymieniać argumenty pojedynczo:

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"                                     
CuriousSuperhero
źródło
1
Czy to oznacza, że ​​różnica polega na tym, że Bind jest zamknięciem?
Gregory R.,
Właśnie nauczyłeś mnie o funkcji argumentów używanej wewnątrz funkcji poprzez twój fragment kodu. Warto wspomnieć, "use strict"aby uniknąć zastępowania takich zastrzeżonych słów kluczowych. +1.
RBT
@Max zgodził się; Przesłałem zmianę, w której „to” jest nieprawidłowe lub nie ma sensu, dopóki nie użyjemy bind / call / apply
iono
1
Dzięki za sugestie ulepszeń. Trochę zredagowałem swoją odpowiedź. @iono Twoja sugestia zawierała pewne nieścisłości, więc nie mogłem jej zatwierdzić, ale wprowadziłem własne zmiany w odpowiedzi. Mam nadzieję, że jest teraz bardziej kompleksowy.
CuriousSuperhero
199

Odpowiedz w najprostszej formie

  • Wywołanie wywołuje funkcję i umożliwia przekazywanie argumentów jeden po drugim.
  • Apply wywołuje funkcję i pozwala przekazywać argumenty jako tablicę.
  • Bind zwraca nową funkcję, która pozwala przekazać tę tablicę i dowolną liczbę argumentów.

Przykłady zastosowania vs. połączenia i powiązania

Połączenie

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

Zastosować

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

Wiązać

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

Kiedy używać każdego z nich

Dzwoń i aplikuj są dość wymienne. Po prostu zdecyduj, czy łatwiej jest wysłać tablicę lub listę argumentów oddzieloną przecinkami.

Zawsze pamiętam, który to jest, pamiętając, że Call jest przecinkiem (lista oddzielona), a Apply jest Array.

Bind jest trochę inny. Zwraca nową funkcję. Wywołaj i zastosuj natychmiast uruchom bieżącą funkcję.

Bind jest świetny do wielu rzeczy. Możemy go użyć do curry funkcji, jak w powyższym przykładzie. Możemy wziąć prostą funkcję hello i zmienić ją w helloJon lub helloKelly. Możemy go również używać do wydarzeń takich jak onClick, w których nie wiemy, kiedy zostaną zwolnieni, ale wiemy, w jakim kontekście chcemy, aby były.

Odniesienie: codeplanet.io

Amit Shah
źródło
8
Niesamowita odpowiedź, jeśli to byłby mój post z pytaniem, daję WAS.
AmerllicA,
W calli apply, czy wynika z tego, że jeśli nie masz thismetody wewnątrz, to przypisujesz pierwszy argument jako null?
Daryll Santos
1
@DaryllSantos, Według MDN: thisArg Opcjonalne. Wartość podana dla wywołania funkcji. Zauważ, że może to nie być rzeczywista wartość widziana przez metodę: jeśli metoda jest funkcją w trybie nieokreślonym, wartości puste i niezdefiniowane zostaną zastąpione obiektem globalnym, a wartości pierwotne zostaną przekonwertowane na obiekty. Więc jeśli nie użyjesz tego w funkcji, nie ma to znaczenia.
Amit Shah
4
call = = przecinek, zastosuj == tablica była fajną sztuczką zapamiętywania
drlff
var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanDziała idealnie dobrze i wyświetla VM128: 4 Hello Jon
Kuperman
53

Pozwala ustawić wartość thisniezależną od sposobu wywoływania funkcji. Jest to bardzo przydatne podczas pracy z wywołaniami zwrotnymi:

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

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

Aby osiągnąć ten sam wynik call, wyglądałoby to tak:

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

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
jantimon
źródło
5
Wykorzystanie tego .bind(), co pokazałeś wcześniej, jest nieprawidłowe. Gdy użyjesz fn.bind(obj)innej funkcji, zostanie zwrócona (nie wcześniej utworzona). I nie ma możliwości zmiany wartości thiswnętrza bindedfunkcji. Najczęściej jest to wykorzystywane do thisubezpieczenia oddzwaniania . Ale w twoim przykładzie - nie ma różnic w wyniku. Ale fn !== fn.bind(obj);zauważ to.
ValeriiVasin
@InviS Nie rozumiem twojego komentarza - dlaczego nie jest inaczej?
jantimon
2
Różnica w połączeniach i zastosowaniach jest. w wywołaniu przekazujesz argumenty jako ciągi rozdzielone przecinkami, natomiast w zastosowaniu możesz przekazywać argumenty w postaci tablicy. reszta są takie same.
Ashish Yadav
ciągi rozdzielone przecinkami ? wystarczy przekazać argumenty jako przecinek oddzielony !!
Sudhansu Choudhary,
46

Załóżmy, że mamy multiplicationfunkcję

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

Stwórzmy standardowe funkcje za pomocą bind

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

Teraz multiby2 (b) jest równe mnożeniu (2, b);

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

Co jeśli przekażę oba parametry w powiązaniu

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

Teraz getSixAlways () jest równe mnożeniu (3,2);

getSixAlways();//6

nawet przekazanie parametru zwraca 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Tworzy to nową funkcję mnożenia i przypisuje ją do magicMultiplication.

O nie, ukrywamy funkcję mnożenia w magicMultiplication.

wywołanie magicMultiplicationzwraca puste miejscefunction b()

po wykonaniu działa dobrze magicMultiplication(6,5); //30

A może zadzwonisz i złożysz podanie?

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

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

Krótko mówiąc, bindtworzy funkcję calli applywykonuje funkcję, a jednocześnie applyoczekuje parametrów w tablicy

tk120404
źródło
Bardzo dobrze wyjaśnione!
CatalinBerta,
3
+1 dla „W prostych słowach bindtworzy funkcję calli applywykonuje funkcję, a jednocześnie applyoczekuje parametrów w tablicy”
Josh Buchea
32

Zarówno Function.prototype.call()i Function.prototype.apply()wywołać funkcję z danej thiswartości i powrót wartości zwracanej tej funkcji.

Function.prototype.bind(), z drugiej strony, tworzy nową funkcję o podanej thiswartości i zwraca tę funkcję bez jej wykonania.

Weźmy więc funkcję, która wygląda następująco:

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

A teraz weźmy obiekt, który wygląda następująco:

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

Możemy powiązać naszą funkcję z naszym obiektem w następujący sposób:

Obj.log = logProp.bind(Obj);

Teraz możemy uruchomić w Obj.logdowolnym miejscu naszego kodu:

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

Ciekawe staje się wtedy, gdy nie tylko przypisujesz wartość this, ale również argument prop:

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

Możemy teraz to zrobić:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
John Slegers
źródło
23

bind : wiąże funkcję z podaną wartością i kontekstem, ale nie wykonuje funkcji. Aby wykonać funkcję, musisz wywołać funkcję.

call : Wykonuje funkcję z podanym kontekstem i parametrem.

Apply : Wykonuje funkcję z podanym kontekstem i parametrem jako tablica .

Siddhartha
źródło
proste i pokorne!
Habeeb Perwad
18

Oto jeden dobry artykuł , aby zilustrować różnicę między bind(), apply()i call(), podsumować, jak poniżej.

  • bind()pozwala nam łatwo ustawić, który konkretny obiekt będzie z tym związany, gdy zostanie wywołana funkcja lub metoda.

    // 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() pozwalają nam pożyczyć metody

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

    Jednym z problemów w tym przykładzie jest to, że dodajemy nową metodę showDatado carsobiektu i możemy nie chcieć tego robić, aby pożyczyć metodę, ponieważ obiekt cars może już mieć nazwę właściwości lub metody showData. Nie chcemy go przypadkowo zastąpić. Jak zobaczymy w naszym omówieniu Applyi Callponiżej, najlepiej pożyczyć metodę za pomocą metody Applylub Call.

  • bind() pozwól nam wywołać funkcję

    Funkcja Currying , znana również jako aplikacja funkcji częściowej , to użycie funkcji (która akceptuje jeden lub więcej argumentów), która zwraca nową funkcję z niektórymi ustawionymi argumentami.

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

    Możemy użyć bind()do curry tej greetfunkcji

    // 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()lub call()ustawić wartość

    Te apply, calloraz bindwszystkie metody są stosowane w celu ustawienia tej wartości podczas wywoływania metody, i robią to w nieco inny sposób, aby umożliwić zastosowanie bezpośrednią kontrolę i wszechstronność w naszym kodzie JavaScript.

    applyI callmetody są niemal identyczne przy ustalaniu tej wartości poza tym, że można przejść do parametrów funkcji apply ()jako macierzy , podczas gdy masz do listy parametrów indywidualnie przekazać je do call ()metody.

    Oto jeden przykład użycia calllub applyustawienia tego w funkcji oddzwaniania.

    // 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
  • Pożycz funkcje za pomocą applylubcall

    • Metody Borrow Array

      Stwórzmy array-likeobiekt i pożyczmy kilka metod tablicowych do działania na naszym obiekcie podobnym do tablicy.

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

      Innym częstym przypadkiem jest konwersja argumentsna tablicę w następujący sposób

        // 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"]
    • Pożycz inne metody

      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​
  • Służy apply()do wykonywania funkcji zmiennej-arity

Jest Math.maxto jeden przykład funkcji zmiennej-arity,

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

Ale co, jeśli mamy tablicę liczb do przekazania Math.max? Nie możemy tego zrobić:

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

To tutaj apply ()metoda pomaga nam wykonywać funkcje variadic . Zamiast powyższego musimy przekazać tablicę liczb za pomocą apply () w ten sposób:

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
źródło
8

zadzwoń / zastosuj natychmiast wykonuje funkcję:

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

bind nie wykonuje funkcji natychmiast, ale zwraca opakowaną funkcję Apply (do późniejszego wykonania):

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}
Eldiyar Talantbek
źródło
7

Składnia

  • wywołanie (thisArg, arg1, arg2, ...)
  • zastosowanie (thisArg, argsArray)
  • bind (thisArg [, arg1 [, arg2 [, ...]]])

Tutaj

  • thisArg jest obiektem
  • argArray jest obiektem tablicowym
  • arg1, arg2, arg3, ... to dodatkowe argumenty

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
źródło
6

Podstawowa różnica między Call, Apply i Bind to:

Powiązanie zostanie użyte, jeśli chcesz, aby kontekst wykonania pojawił się później na obrazie.

Dawny:

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

Powiedzmy, że chcę użyć tej metody w innej zmiennej

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

Aby użyć odniesienia do samochodu w innej zmiennej, powinieneś użyć

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

Porozmawiajmy o szerszym użyciu funkcji wiązania

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

func();
// Number: 1

Dlaczego? Ponieważ teraz func jest powiązany z numerem 1, jeśli nie użyjemy wiązania w tym przypadku, wskaże on obiekt globalny.

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

func();
// Object

Połączenia, Zastosuj są używane, gdy chcesz wykonać instrukcję w tym samym czasie.

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
źródło
4

Zadzwoń, zastosuj i zwiąż. i jak się różnią.

Pozwala nauczyć się dzwonić i aplikować przy użyciu codziennej terminologii.

Masz trzy samochody, your_scooter , your_car and your_jetktóre zaczynają z tym samym mechanizmem (metodą). Stworzyliśmy obiekt automobileza pomocą metody 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");
    }
}

Pozwala zrozumieć, kiedy jest używany i zadzwoń. Załóżmy, że jesteś inżynierem i tak jest your_scooter, your_cara your_jetktóry nie był wyposażony w funkcję push_button_engine_start i chcesz korzystać z usług innej firmy push_button_engineStart.

Jeśli uruchomisz następujące wiersze kodu, dadzą błąd. DLACZEGO?

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

Tak więc powyższy przykład z powodzeniem nadaje twojemu skuterowi, twojemu samochodowi, twojemu atramentowi funkcję obiektu samochodowego.

Zanurkujmy głębiej Tutaj podzielimy powyższą linię kodu. automobile.push_button_engineStartpomaga nam uzyskać zastosowaną metodę.

Ponadto używamy zastosowania lub połączenia za pomocą notacji kropkowej. automobile.push_button_engineStart.apply()

Teraz zastosuj i zaakceptuj dwa parametry.

  1. kontekst
  2. argumenty

Tutaj ustawiamy kontekst w ostatnim wierszu kodu.

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

Różnica między wywołaniem a zastosowaniem polega na tym, że zastosowanie akceptuje parametry w postaci tablicy, podczas gdy wywołanie może po prostu zaakceptować listę argumentów oddzieloną przecinkami.

Co to jest funkcja JS Bind?

Funkcja powiązania to po prostu powiązanie kontekstu czegoś, a następnie zapisanie go w zmiennej do wykonania na późniejszym etapie.

Uczyńmy nasz poprzedni przykład jeszcze lepszym. Wcześniej używaliśmy metody należącej do obiektu samochodowego i używaliśmy jej do wyposażenia your_car, your_jet and your_scooter. Teraz wyobraźmy sobie, że chcemy osobno dać push_button_engineStartosobno, aby osobno uruchomić nasze samochody na dowolnym późniejszym etapie realizacji.

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

nadal nie jesteś zadowolony?

Wyjaśnijmy to jak łzy. Czas na eksperyment. Wrócimy do wywołania i zastosowania aplikacji funkcji i spróbujemy zapisać wartość funkcji jako odniesienie.

Poniższy eksperyment kończy się niepowodzeniem, ponieważ wywołanie i zastosowanie są wywoływane natychmiast, dlatego nigdy nie przechodzimy do etapu przechowywania odwołania w zmiennej, w której funkcja wiązania kradnie przedstawienie

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

Sagar Munjal
źródło
3

Wywołanie: wywołanie wywołuje funkcję i umożliwia przekazywanie argumentów jeden po drugim

Apply: Apply wywołuje funkcję i umożliwia przekazywanie argumentów jako tablicy

Bind: Bind zwraca nową funkcję, umożliwiając przekazanie w tej tablicy i dowolnej liczbie argumentów.

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
źródło
2

call (): - Tutaj przekazujemy argumenty funkcji indywidualnie, a nie w formacie tablicowym

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 (): - Tutaj przekazujemy argumenty funkcji w formacie tablicowym

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
źródło
2

Wywołanie 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)

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

** funkcje call i apply są różnicami call weź osobny argument, ale zastosuj tablicę take: [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
źródło
1

Wyobraź sobie, że powiązanie nie jest dostępne. możesz łatwo zbudować go w następujący sposób:

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

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

bindHelper(arguments);
Philippe Oceangermanique
źródło
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
źródło
0

Główną koncepcją wszystkich tych metod jest zakrywanie funkcji .

Pożyczanie funkcji pozwala nam korzystać z metod jednego obiektu na innym obiekcie bez konieczności wykonywania kopii tej metody i utrzymywania jej w dwóch osobnych miejscach. Dokonuje się tego poprzez użycie. połączenie() , . Apply () lub. bind (), z których wszystkie istnieją, aby jawnie ustawić to na metodę, którą pożyczamy

  1. Wywołanie wywołuje funkcję natychmiast i umożliwia przekazywanie argumentów jeden po drugim
  2. Apply natychmiast wywołuje funkcję i pozwala przekazywać argumenty jako tablicę .
  3. Bind zwraca nową funkcję i możesz ją wywołać / wywołać w dowolnym momencie, wywołując funkcję.

Poniżej znajduje się przykład wszystkich tych metod

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

POŁĄCZENIE

pierwszy argument, np. nazwa w metodzie wywołania, zawsze odnosi się do (tej) zmiennej, a drugi będzie zmienną funkcyjną

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

ZASTOSOWAĆ

metoda Apply jest taka sama jak metoda call, jedyną różnicą jest to, że argumenty funkcji są przekazywane na liście Array

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

WIĄZAĆ

Metoda powiązania jest taka sama jak wywołanie, z tą różnicą, że powiązanie zwraca funkcję, która może być później użyta przez jej wywołanie (nie wywołuje go natychmiast)

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

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

printMyNAme () to funkcja, która wywołuje tę funkcję

poniżej znajduje się link do jsfiddle

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

Arham Chowdhury
źródło
-1

Myślę, że są to te same miejsca: wszystkie mogą zmienić tę wartość funkcji. Różnice między nimi: funkcja bind zwróci w wyniku nową funkcję; metody wywołania i zastosowania natychmiast wykonają tę funkcję, ale funkcja Apply może zaakceptować tablicę jako parametry i przeanalizuje tablicę oddzielnie, a także funkcją wiązania może być Currying.

Xin Tao
źródło
-3

funkcja bind powinna być używana, gdy chcemy przypisać funkcję o określonym kontekście np.

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

w powyższym przykładzie, jeśli wywołamy funkcję demo.setValue () i przekażemy tę funkcję.getValue bezpośrednio, wówczas nie wywołuje ona funkcji demo.setValue bezpośrednio, ponieważ to w setTimeout odnosi się do obiektu okna, więc musimy przekazać kontekst obiektu demo do this.getValue funkcja za pomocą bind. oznacza to, że przekazujemy funkcję tylko w kontekście obiektu demonstracyjnego, który nie wywołuje funkcji.

Mam nadzieję, że rozumiesz .

Aby uzyskać więcej informacji, zapoznaj się z funkcją wiązania javascript

użytkownik7339156
źródło