Вызов Javascript () и apply () против 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 3-е издание. У SO есть такие вопросы, как: что такое разница между вызовом и применением . Я только догадываюсь, хотя, как мне было интересно, что сам.
Нет
вам нужны эти методы (вызов, применение, связывание) здесь ?? без этого вы также можете вызвать метод, и это будет указывать только на объект
Махи
Оформить
techyaura

Ответы:

131

Я создал это сравнение между объектами функций, вызовами функций call/applyи bindнекоторое время назад:

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

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

Феликс Клинг
источник
779

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

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 для асинхронных обратных вызовов, для которых я хочу передать метод member, но все же хочу, чтобы контекст был экземпляром, который запустил асинхронное действие.

Простая, наивная реализация bind будет выглядеть так:

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 аналогично call, за исключением того, что он принимает массивоподобный объект вместо перечисления аргументов по одному:

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
источник
1
Означает ли это, что Bind является закрытием?
Грегори Р.
Вы только что рассказали мне о функции аргументов, используемой внутри функции через ваш фрагмент кода. Рекомендуется упомянуть, "use strict"чтобы избежать переопределения таких зарезервированных ключевых слов. +1.
RBT
@ Макс согласился; Я отправил правку, в которой «this» неверно или не имеет смысла, пока мы не используем bind / call / apply
iono
1
Спасибо за предложения по улучшению. Я немного отредактировал свой ответ. @iono В вашем предложении были некоторые неточности, поэтому я не смог его одобрить, но я внес свои правки в ответ. Надеюсь, теперь это более всеобъемлющее.
CuriousSuperhero
200

Ответ в простейшей форме

  • Вызов вызывает функцию и позволяет передавать аргументы один за другим.
  • Apply вызывает функцию и позволяет передавать аргументы в виде массива.
  • Bind возвращает новую функцию, позволяющую передавать массив this и любое количество аргументов.

Примеры «Применить против колла» против «Привязки»

Вызов

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 для Array.

Привязка немного отличается. Возвращает новую функцию. Вызвать и применить немедленно выполнить текущую функцию.

Bind отлично подходит для многих вещей. Мы можем использовать его для карри функций, как в примере выше. Мы можем взять простую функцию hello и превратить ее в 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);
jantimon
источник
5
Использование того, .bind()что вы показали ранее, неверно. При использовании fn.bind(obj)другой функции будет возвращено (не то, что вы создали ранее). И нет никаких возможностей изменить значение thisвнутри bindedфункции. В основном это используется для thisстрахования обратных вызовов . Но в вашем примере - нет различий в результате. Но fn !== fn.bind(obj);обратите внимание на это.
Валерий Васин
@ InviS Я не понимаю ваш комментарий - почему нет ничего другого?
Январь
2
Разница в вызове и применении есть. при вызове вы передаете аргументы в виде строк, разделенных запятыми, а при применении вы можете передавать аргументы в виде массива. Остальные же.
Ашиш Ядав
разделенные запятой строки ?? просто передавайте аргументы как запятую !!
Судхансу Чоудхари
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.

О нет, мы скрываем функциональность умножения в magicMultiplication.

вызов magicMultiplicationвозвращает пустоеfunction b()

на исполнении все работает отлично magicMultiplication(6,5); //30

Как насчет звонить и подать заявку?

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

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

Проще говоря, bindсоздает функцию callи applyвыполняет функцию, тогда как applyожидает параметры в массиве

tk120404
источник
Очень хорошо объяснил!
CatalinBerta
3
+1 для «Простыми словами, bindсоздает функцию callи applyвыполняет функцию, в то applyвремя как ожидает параметры в массиве»
Джош Буче
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 : связывает функцию с предоставленным значением и контекстом, но не выполняет функцию. Для выполнения функции необходимо вызвать функцию.

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

apply : выполняет функцию с предоставленным контекстом и параметром в виде массива .

Сиддхартха
источник
просто и скромно!
Хабиб Perwad
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объекту, и мы можем не захотеть делать это просто для того, чтобы заимствовать метод, потому что объект cars может уже иметь имя свойства или метода showData. Мы не хотим перезаписывать это случайно. Как мы увидим в нашем обсуждении Applyи Callниже, лучше всего заимствовать метод, используя либо метод, Applyлибо Call.

  • bind() позвольте нам выполнить функцию

    Функция Curry , также известная как частичное применение функции , - это использование функции (которая принимает один или несколько аргументов), которая возвращает новую функцию с некоторыми из уже установленных аргументов.

    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
zangw
источник
8

call / apply немедленно выполняет функцию:

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

bind не выполняет функцию сразу, но возвращает упакованную функцию apply (для последующего выполнения):

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}
Эльдияр Талантбек
источник
7

Синтаксис

  • вызов (thisArg, arg1, arg2, ...)
  • применить (thisArg, argsArray)
  • bind (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

Почему? Потому что теперь func связан с Number 1, и если мы не будем использовать bind, в этом случае он будет указывать на Global Object.

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

func();
// Object

Call, Apply используются, когда вы хотите выполнить инструкцию одновременно.

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

Таким образом, приведенный выше пример успешно предоставляет your_scooter, your_car, your_jet функцию из автомобильного объекта.

Давайте погрузимся глубже. Здесь мы разделим вышеприведенную строку кода. automobile.push_button_engineStartпомогает нам получить используемый метод.

Далее мы используем apply или call с использованием точечной нотации. automobile.push_button_engineStart.apply()

Теперь примените и вызовите принять два параметра.

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

Итак, здесь мы устанавливаем контекст в последней строке кода.

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

Разница между call и apply заключается в том, что apply принимает параметры в виде массива, в то время как call может просто принимать список аргументов через запятую.

что такое функция 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);

все еще не удовлетворены?

Давайте сделаем это ясно, как слеза. Время экспериментировать. Мы вернемся к вызову и применим функцию application и попытаемся сохранить значение функции в качестве ссылки.

Приведенный ниже эксперимент не удался, потому что call и apply вызываются немедленно, следовательно, мы никогда не доберемся до стадии сохранения ссылки в переменной, где функция bind перехватывает показ

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

Сагар Мунджал
источник
3

Call: call вызывает функцию и позволяет передавать аргументы один за другим.

Apply: Apply вызывает функцию и позволяет передавать аргументы в виде массива.

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

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

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

** вызов и применение функции являются разностным вызовом, принимают отдельный аргумент, но применяют массив массива, например: [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
источник
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;
pandhari
источник
0

Основной концепцией всех этих методов является функция рытья .

Заимствование функций позволяет нам использовать методы одного объекта на другом объекте без необходимости делать копию этого метода и хранить его в двух разных местах. Это достигается с помощью. вызов() , . применить () или. bind (), все из которых существуют, чтобы явно установить это для метода, который мы заимствуем

  1. Вызов немедленно вызывает функцию и позволяет передавать аргументы один за другим.
  2. Apply немедленно вызывает функцию и позволяет передавать аргументы в виде массива .
  3. Bind возвращает новую функцию, и вы можете вызывать / вызывать ее в любое время, вызвав функцию.

Ниже приведен пример всех этих методов

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

ВЫЗОВ

первый аргумент, например имя внутри метода вызова, всегда является ссылкой на (this) переменную, а последний будет переменной функции

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

ПРИМЕНЯТЬ

Метод apply аналогичен методу вызова, единственное отличие состоит в том, что аргументы функции передаются в списке Array.

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

BIND

Метод bind аналогичен call, за исключением того, что bind возвращает функцию, которую можно использовать позже, вызвав ее (не вызывает ее сразу)

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

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

printMyNAme () - это функция, которая вызывает функцию

ниже ссылка для jsfiddle

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

Архам Чоудхури
источник
-1

Я думаю, что одни и те же места: все они могут изменять значение функции this. Различия между ними: функция bind вернет новую функцию в результате; методы call и apply сразу же выполнят функцию, но apply может принять массив в качестве параметров и проанализировать разделенный массив. А также, функция bind может быть Curry.

Синь Тао
источник
-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 напрямую, поскольку this в setTimeout ссылается на объект окна, поэтому нам нужно передать контекст демо-объекта в this.getValue Функция с использованием связывания. это означает, что мы только передаем функцию в контексте демонстрационного объекта, а не вызываем функцию.

Надеюсь, ты понимаешь.

Для получения дополнительной информации, пожалуйста, обратитесь к функции привязки javascript.

user7339156
источник