Виклик Javascript () та застосувати () проти bind ()?


794

Я вже це знаю applyі callє подібними функціями, які задаються this(контекст функції).

Різниця полягає в тому, як ми надсилаємо аргументи (керівництво проти масиву)

Питання:

Але коли я повинен використовувати bind()метод?

var obj = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));

jsbin


9
Це не ваша вина, якщо є користувачі, які переглядають точки репутації ОП перед тим, як опублікувати відповідь чи підтвердити :)
Габріель Лламас

54
зателефонувати та застосувати функцію виклику, тоді як прив'язка створює функцію. Хоча зcall()вами передайте аргументи індивідуально іapply()як масив аргументів. Для отримання більш детальної інформації перегляньте зв'язану документацію, яка повинна мати можливість повністю відповісти на ваше питання
Ніп

3
kind of weird there is not an existing question about this :Щодо цього. Це, мабуть, тому, що bind()було додано після того, як два інших вже існували в JavaScript 1.8.5 - ECMA-262, 5-е видання. Поки call()і apply()існували з часу JavaScript 1.3 - ECMA-262 3rd Edition. Так у них є такі питання, як: що-що-різниця-між дзвінками-і-застосувати . Я лише здогадуюсь, хоч як мені це було цікаво.
Nope

чи потрібні вам ці методи (дзвоніть, застосовуйте, зв'язуйте) тут ?? без цього ви також можете зателефонувати за методом, і це вкаже лише на заперечення
Mahi

замовити посилання - techyaura-blogs.blogspot.com/2020/05/…
techyaura

Відповіді:


131

Я створив це порівняння між об'єктами функцій, викликами функцій call/applyі bindдеяким часом тому:

введіть тут опис зображення

.bindдозволяє встановити thisзначення зараз , дозволяючи виконувати функцію в майбутньому , оскільки вона повертає новий об’єкт функції.


779

Використовуйте, .bind()коли ви хочете, щоб ця функція пізніше була викликана з певним контекстом, корисним у подіях. Використовуйте .call()або .apply()коли ви хочете негайно викликати функцію та змініть контекст.

Виклик / застосуйте функцію виклику негайно, тоді як bindповертає функцію, яка після виконання буде мати правильний контекст для виклику вихідної функції. Таким чином ви можете підтримувати контекст у асинхронних зворотах і подіях.

Я цим займаюся багато:

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

Я широко використовую його в Node.js для зворотних викликів async, для яких я хочу передати метод-член, але все ж хочу, щоб контекст був екземпляром, який запустив дію async.

Проста, наївна реалізація палітурки буде такою:

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

У ньому є більше (як передача інших аргументів), але ви можете прочитати більше про нього і побачити реальну реалізацію на MDN .

Сподіваюсь, це допомагає.


2
@RoyiNamir це правильно, ви можете використовувати повернуту функцію "прив'язаний" пізніше, і контекст буде підтримуватися.
Чад

5
Саме це і bindповертає.
Чад

@RoyiNamir Відредагував мою відповідь
Чад

4
Ви також можете використовувати bind для партій, передаючи аргументи до виклику функції.
Ендрю Кіркегор

1
Ви просто повторюєте прив'язку, різниці насправді немає. У будь-якому випадку ви просто загортаєте його в закриття, яке має доступ до змінної області, що містить контекст. Ваш код - це в основному поліфайл, який я розмістив.
Чад

446

Всі вони приєднують це до функції (або об'єкта), а різниця полягає у виклику функції (див. Нижче).

call додає це до функції та виконує функцію негайно:

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 приєднує це до функції, і його потрібно викликати окремо так:

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"

або так:

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

Apply є аналогічним виклику, за винятком того, що він займає об'єкт, схожий на масив, а не перераховувати аргументи один за одним:

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
Чи означає це, що різниця полягає в тому, що Bind - це закриття?
Григорій Р.

Ви просто навчили мене про аргументи, які використовуються у функції через ваш фрагмент коду. Доцільно згадати, "use strict"щоб уникнути перекреслення таких зарезервованих ключових слів. +1.
RBT

@Max погодився; Я подав правку, де "це" неправильно або не має сенсу, поки ми не використовуємо прив'язку / виклик / застосувати
iono

1
Дякуємо за пропозиції щодо вдосконалення. Я трохи відредагував свою відповідь. @iono Ваша пропозиція мала деякі неточності, тому не могла її затвердити, але я змінила відповіді. Сподіваємось, це зараз всебічніше.
CuriousSuperhero

199

Відповідь у найпростішій формі

  • Call викликає функцію та дозволяє передавати аргументи по черзі.
  • Застосувати виклики функції та дозволяє передавати аргументи у вигляді масиву.
  • Bind повертає нову функцію, що дозволяє передавати цей масив і будь-яку кількість аргументів.

Застосувати приклади проти дзвінків проти прив'язки

Дзвінок

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

Застосувати

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

Прив’яжи

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

Коли використовувати кожен

Дзвінки та подання заявок досить взаємозамінні. Просто вирішіть, чи простіше надіслати масив чи список аргументів, розділених комами.

Я завжди пам’ятаю, який з них, пам’ятаючи, що Call - це кома (окремий список), а Apply - для масиву.

Бінд трохи інший. Він повертає нову функцію. Зателефонувати та застосувати, виконайте поточну функцію негайно.

Бінд чудово підходить для багатьох речей. Ми можемо використовувати його для curry функцій, як у наведеному вище прикладі. Ми можемо взяти просту функцію привіт і перетворити її на helloJon або helloKelly. Ми також можемо використовувати його для подій, таких як onClick, коли ми не знаємо, коли вони будуть звільнені, але ми знаємо, який контекст ми хочемо мати.

Довідка: codeplanet.io


8
Дивовижна відповідь, якщо це був мій пост запитання, я даю ВАМ галочку.
AmerllicA

В callі applyчи випливає, що якщо у вас немає thisметоду всередині, ви призначили перший аргумент як null?
Дарілл Сантос

1
@DaryllSantos, За даними MDN: thisArg Необов’язковий. Значення цього передбачено для виклику функції. Зауважте, що це може бути не фактичне значення, яке бачить метод: якщо метод є функцією в не суворому режимі, нульові та невизначені будуть замінені глобальним об'єктом, а примітивні значення перетворяться на об'єкти. Тож якщо ви не використовуєте це у функції, це не має значення.
Аміт Шах

4
call = = кома, застосувати масив == було приємним трюком запам'ятовування
drlff

var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanВідмінно працює і видає VM128: 4 Привіт Джон Куперман
Пратік

53

Це дозволяє встановити значення thisнезалежно від того, як викликається функція. Це дуже корисно при роботі з зворотними дзвінками:

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

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

Для досягнення такого ж результату callбуло б виглядати так:

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

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

5
Використання, .bind()як ви показали раніше, неправильне. При використанні fn.bind(obj)іншої функції буде повернуто (не те, що ви створювали раніше). І немає здібностей змінювати значення thisвнутрішньої bindedфункції. В основному це використовується для thisстрахування зворотних дзвінків. Але у вашому прикладі - різниці в результаті немає. Але fn !== fn.bind(obj);зауважте це.
ВалерійВасін

@InviS Я не розумію ваш коментар - чому немає іншого?
jantimon

2
Різниця між дзвінками та заявками є. у виклику ви передаєте аргументи у вигляді рядків, розділених комами, тоді як у застосуванні ви можете передавати аргументи у вигляді масиву. відпочинок той самий.
Ашиш Ядав

рядки, розділені комами ?? просто передайте аргументи як розділені комами !!
Sudhansu Choudhary

46

Припустимо, у нас є multiplicationфункція

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

Дозволяє створювати деякі стандартні функції за допомогою bind

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

Тепер multiby2 (b) дорівнює множенню (2, b);

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

Що робити, якщо я передаю обидва параметри у прив'язку

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

Тепер getSixAlways () дорівнює множенню (3,2);

getSixAlways();//6

навіть рівний параметр повертає 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Це створює нову функцію множення і привласнює її до магічного множення.

О ні, ми приховуємо функцію множення в магію Множення.

виклик magicMultiplicationповертає порожнєfunction b()

по виконанню це працює чудово magicMultiplication(6,5); //30

Як щодо дзвінка та подати заявку?

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

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

Простими словами, bindстворює функцію callі applyвиконує функцію, тоді як applyочікує параметри в масиві


Дуже добре пояснено!
CatalinBerta

3
+1 для "Простими словами, bindстворює функцію callта applyвиконує функцію, тоді як applyочікує параметри в масиві"
Josh Buchea

32

Обидва Function.prototype.call()і Function.prototype.apply()викликають функцію із заданим thisзначенням, і повертають повернене значення цієї функції.

Function.prototype.bind()з іншого боку, створює нову функцію із заданим thisзначенням та повертає цю функцію, не виконуючи її.

Отже, візьмемо функцію, яка виглядає приблизно так:

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

Тепер візьмемо об’єкт, який виглядає приблизно так:

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

Ми можемо прив’язати свою функцію до нашого об'єкта так:

Obj.log = logProp.bind(Obj);

Тепер ми можемо працювати в Obj.logбудь-якому місці нашого коду:

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

Де це дійсно стає цікавим, це коли ви прив'язуєте не тільки значення для this, але і для його аргументу prop:

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

Тепер ми можемо це зробити:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10

23

bind : вона пов'язує функцію із заданим значенням та контекстом, але вона не виконує функцію. Для виконання функції потрібно викликати функцію.

виклик : він виконує функцію із заданим контекстом та параметром.

застосовується : він виконує функцію з наданим контекстом і параметром як масив .


простий і смиренний!
Хабіб Первад

18

Ось одна хороша стаття , щоб проілюструвати різницю між bind(), apply()і call(), узагальнювати його , як показано нижче.

  • bind()дозволяє нам легко встановити, який конкретний об'єкт буде пов'язаний з цим, коли викликається функція або метод.

    // 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() дозволяють запозичити методи

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

    Одна з проблем цього прикладу полягає в тому, що ми додаємо новий метод showDataна carsоб’єкт, і ми можемо не хотіти цього робити лише для запозичення методу, оскільки об'єкт "автомобілі" вже може мати ім'я властивості або методу showData. Ми не хочемо їх перезаписати випадково. Як ми побачимо в нашому обговоренні Applyта Callнижче, найкраще запозичити метод, використовуючи Applyабо Callметод, або метод.

  • bind() дозволяємо нам викрити функцію

    Функція Currying , також відома як додатки часткової функції , - це використання функції (яка приймає один або більше аргументів), яка повертає нову функцію з деякими з уже встановлених аргументів.

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

    Ми можемо використовувати bind()цю greetфункцію

    // 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()або call()встановити це значення

    Усі apply, callі, bindметоди використовуються для встановлення цього значення при виклику методу, і вони роблять це дещо по-різному, щоб дозволити використовувати прямий контроль та універсальність у нашому коді JavaScript.

    При встановленні цього значення методи applyта callметоди майже ідентичні, за винятком того, що ви передаєте параметри функції apply ()як масив , тоді як вам доведеться перераховувати параметри окремо, щоб передати їх call ()методу.

    Ось один приклад використання callабо applyвстановлення цього параметра у функції зворотного виклику.

    // 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
  • Функції запозичення з applyабоcall

    • Методи масиву запозичень

      Створимо array-likeоб’єкт і запозичимо кілька методів масиву для роботи з нашим об’єктом, схожим на масив.

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

      Іншим поширеним випадком є ​​перетворення argumentsв масив наступним чином

        // 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"]
    • Позичіть інші методи

      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​
  • Використовуйте apply()для виконання змінної арності функції

Це Math.maxодин із прикладів функції змінної аритності,

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

Але що робити, якщо у нас є масив чисел для передачі Math.max? Ми не можемо цього зробити:

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

Саме тут apply ()метод допомагає нам виконувати різні функції . Замість вищезазначеного ми маємо передати масив чисел, використовуючи apply () таким чином:

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

функція виконувати виклик / застосувати виконується негайно:

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

bind не виконує функцію відразу, але повертає завернуту функцію застосування (для подальшого виконання):

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}

7

Синтаксис

  • виклик (thisArg, arg1, arg2, ...)
  • застосувати (thisArg, argsArray)
  • прив’язати (thisArg [, arg1 [, arg2 [, ...]]])

Ось

  • thisArg є об'єктом
  • argArray - це об'єкт масиву
  • arg1, arg2, arg3, ... - це додаткові аргументи

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

Основна різниця між Call, Apply та Bind:

Прив'язка буде використана, якщо ви хочете, щоб ваш контекст виконання з’явився пізніше на малюнку.

Наприклад:

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

Скажімо, я хочу використовувати цей метод у якійсь іншій змінній

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

Для використання посилання автомобіля в якійсь іншій змінній вам слід скористатися

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

Поговоримо про більш широке використання функції зв’язування

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

func();
// Number: 1

Чому? Оскільки тепер функція прив'язується до числа 1, якщо ми не використовуємо прив'язку в цьому випадку, вона вказуватиме на глобальний об’єкт.

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

func();
// Object

Дзвінок, застосувати використовуються, коли ви хочете виконати операцію одночасно.

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

Дзвінок подати та зв’язати. і чим вони різні.

Дозволяє вивчати дзвінки та застосовувати будь-яку денну термінологію.

У вас є три машини, your_scooter , your_car and your_jetякі починаються з однакового механізму (методу). Ми створили об’єкт automobileметодом 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");
    }
}

Давайте зрозуміємо, коли використовується дзвінок і застосувати застосований. Нехай припустимо, що ви інженер, який у вас є your_scooter, your_carі your_jetякий не прийшов із push_button_engine_start, і ви хочете скористатися третьою стороною push_button_engineStart.

Якщо запустити наступні рядки коду, вони дадуть помилку. ЧОМУ?

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

Отже, наведений вище приклад успішно надає вашому_scooter, your_car, your_jet особливість автомобільного об'єкта.

Давайте зануримося глибше Тут ми розділимо вищевказаний рядок коду. automobile.push_button_engineStartдопомагає нам використовувати метод, який використовується.

Далі ми використовуємо застосувати або зателефонувати за допомогою позначення крапки. automobile.push_button_engineStart.apply()

Тепер застосуйте та подзвоніть прийняти два параметри.

  1. контекст
  2. аргументи

Отже, тут ми встановлюємо контекст у заключному рядку коду.

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

Різниця між викликом та застосуванням полягає лише в тому, що прийом приймає параметри у вигляді масиву, тоді як виклик просто може приймати список аргументів, розділених комами.

що таке функція JS Bind?

Функція прив'язки - це в основному зв'язує контекст чогось, а потім зберігає його в змінну для виконання на більш пізньому етапі.

Давайте зробимо наш попередній приклад ще кращим. Раніше ми використовували метод, що належить до автомобільного об'єкта, і використовували його для оснащення your_car, your_jet and your_scooter. Тепер давайте уявимо, що ми хочемо дати окремо push_button_engineStartокремо для запуску наших автомобілів окремо на будь-якому наступному етапі виконання, який ми бажаємо.

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

все ще не задоволений?

Давайте зрозуміємо, як сльоза. Час експериментувати. Ми повернемося до виклику та застосуємо програму функції та спробуємо зберегти значення функції як еталон.

Експеримент нижче не вдається, тому що виклик і застосувати викликаються негайно, отже, ми ніколи не потрапляємо до етапу зберігання посилання у змінній, де функція прив'язки краде показ

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


3

Виклик: виклик викликає функцію та дозволяє передавати аргументи по черзі

Застосувати: Застосувати виклики функції та дозволяє передавати аргументи як масив

Bind: Bind повертає нову функцію, що дозволяє передавати цей масив та будь-яку кількість аргументів.

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 (): - Тут ми передаємо аргументи функції окремо, а не у форматі масиву

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 (): - Тут ми передаємо аргументи функції у форматі масиву

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

2

Виклик 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)

Застосовувати 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])

** функція виклику та застосування - це різниця виклику приймати окремий аргумент, але застосовувати масив take, як: [1,2,3] **

Прив'язка JavaScript ()

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

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()

1

Уявіть, палітурка недоступна. Ви можете легко сконструювати його так:

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

Основна концепція всіх цих методів - функція закопування .

Функція запозичення дозволяє нам використовувати методи одного об’єкта на іншому об'єкті без необхідності робити копію цього методу та підтримувати його в двох окремих місцях. Це здійснюється за допомогою використання. call (),. застосовувати () або. bind (), які існують, щоб явно встановити це в методі, який ми позичаємо

  1. Виклик викликає функцію негайно і дозволяє передавати аргументи по черзі
  2. Застосувати виклики функції негайно і дозволяє передавати аргументи у вигляді масиву .
  3. Bind повертає нову функцію, і ви можете викликати / викликати її в будь-який час, за допомогою виклику функції.

Нижче наводиться приклад усіх цих методів

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

НАЗВАЙТЕ

перший аргумент, наприклад, ім'я всередині методу виклику, завжди посилається на (цю) змінну, а останній буде змінною функції

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

ЗАЯВА

метод застосування такий же, як метод виклику. Єдина розбіжність полягає в тому, що аргументи функції передаються в список масиву

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

СПІЛЬНИЙ

метод прив'язки такий самий, як виклик, за винятком того, що bind повертає функцію, яку можна використовувати пізніше, викликаючи його (не називає його негайно)

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

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

printMyNAme () - функція, яка викликає функцію

нижче - посилання на jsfiddle

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


-1

Я думаю, що місця у них однакові: усі вони можуть змінити це значення функції. Відмінності між ними полягають у тому, що: функція зв’язування поверне нову функцію в результаті; методи виклику та застосувати виконують функцію негайно, але при застосуванні може приймати масив як парами, і він буде аналізувати масив відокремлено.


-3

Функція прив'язки повинна бути використана, коли ми хочемо призначити функцію з певним контекстом, наприклад.

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

у наведеному вище прикладі, якщо ми викликаємо функцію demo.setValue () і передаємо функцію this.getValue безпосередньо, то вона не викликає функцію demo.setValue безпосередньо, тому що це в setTimeout посилається на об’єкт вікна, тому нам потрібно передати контекст демо-об’єкта до this.getValue функція за допомогою прив'язки. це означає, що ми передаємо функцію лише в контексті демонстраційного об'єкта, що не викликає фактично виклику функції.

Сподіваюся, ти зрозумієш.

для отримання додаткової інформації, будь ласка, зверніться до функції прив'язки JavaScript, детально знайте

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.