Javascript call () & uygulamak () vs bind ()?


794

Ben zaten biliyorum applyve callset benzer fonksiyonlar this(bir fonksiyonun bağlamı).

Aradaki fark, argümanları gönderme şeklimizdir (manual vs array)

Soru:

Ancak bind()yöntemi ne zaman kullanmalıyım ?

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
Bir cevap göndermeden veya oylamadan önce OP'nin itibar noktalarına bakan kullanıcılar varsa bu sizin hatanız değil :)
Gabriel Llamas

54
call ve application bind işlev çağırırken bind bir işlev oluşturur. Bununla birlikte,call()bağımsız değişkenleri bağımsız olarak veapply()bir argüman dizisi olarakiletebilirsiniz. Daha fazla ayrıntı için, sorunuzu tamamen yanıtlayabilmesi gereken bağlantılı belgelere bakın.
Hayır

3
kind of weird there is not an existing question about this :Bununla ilgili. Muhtemelen bind()diğer ikisi JavaScript 1.8.5 - ECMA-262, 5. baskıda zaten var olduktan sonra eklendi. İken call()ve apply()JavaScript 1.3 - ECMA-262 3. Baskı beri bu yana olmuştur. SO'nun bunlarla ilgili soruları vardır: çağrı ve uygulama arasındaki fark nedir ? Sadece kendimi merak ettiğim gibi tahmin ediyorum.
Hayır

Burada bu yöntemlere (arama, uygulama, bağlama) ihtiyacınız var mı? bu olmadan da yöntemi çağırabilirsiniz ve bu sadece nesneyi gösterecektir
Mahi

bağlantıyı kontrol edin - techyaura-blogs.blogspot.com/2020/05/…
techyaura

Yanıtlar:


131

Bu karşılaştırmayı işlev nesneleri, işlev çağrıları call/applyve bindbir süre önce oluşturdum:

resim açıklamasını buraya girin

.bindyeni bir işlev nesnesi döndürdüğü için , gelecekte işlevi yürütmenize izin verirken thisdeğeri şimdi ayarlamanıza olanak tanır .


779

.bind()Bu işlevin daha sonra olaylarda yararlı olan belirli bir bağlamla çağrılmasını istediğinizde kullanın . İşlevi hemen çağırmak istediğinizde .call()veya tuşunu kullanın .apply()ve içeriği değiştirin.

Arama / uygulama işlevi hemen bindçağırırken, daha sonra yürütüldüğünde orijinal işlevi çağırmak için doğru içeriğe sahip bir işlevi döndürür. Bu şekilde, zaman uyumsuz geri çağrılarda ve olaylarda içeriği koruyabilirsiniz.

Bunu çok yapıyorum:

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

Ben bir üye yöntemi geçmek istiyorum async geri aramalar için Node.js yaygın olarak kullanın, ama yine de bağlam zaman uyumsuzluk eylemi başlatan örnek olmak istiyorum.

Bağlamanın basit, saf bir uygulaması şöyle olacaktır:

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

Daha fazlası var (diğer argümanları geçmek gibi), ancak daha fazla bilgi edinebilir ve MDN'deki gerçek uygulamayı görebilirsiniz .

Bu yardımcı olur umarım.


2
@RoyiNamir doğru, daha sonra döndürülen "bound" işlevini kullanabilirsiniz ve bağlam korunacaktır.
Çad

5
Bu tam olarak bindgeri döner.
Çad

@RoyiNamir Cevabımı düzenledi
Chad

4
Ayrıca, işlev çağrılmadan önce bağımsız değişkenler ileterek kısmi öğeler için bağlama özelliğini kullanabilirsiniz.
Andrew Kirkegaard

1
Sadece bağlamayı yeniden uyguluyorsun, gerçekten bir fark yok. Her iki durumda da, bağlamı tutan bir kapsam değişkenine erişimi olan bir kapakta sarıyorsunuz. Kodunuz temelde gönderdiğim çok amaçlı dolgudur.
Chad

446

Hepsi bunu işleve (veya nesneye) bağlar ve fark işlev çağrısındadır (aşağıya bakın).

call bunu işleve ekler ve işlevi hemen yürütür:

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"

bağlama verdiği bu fonksiyonun içine ve böyle ayrı ayrı çağrılan gerekiyor:

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"

ya da bunun gibi:

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

uygulamak benzer bağımsız değişkenleri birer birer listelemek yerine dizi benzeri bir nesne alması dışında çağrıya :

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
Bu fark, Bind'in bir Kapatma olduğu anlamına mı geliyor?
Gregory R.

Bana sadece kod snippet'iniz aracılığıyla bir işlevin içinde kullanılan bağımsız değişkenler özelliğini öğrettiniz. Bu "use strict"tür ayrılmış anahtar kelimeleri geçersiz kılmaktan kaçınmanız önerilir . +1.
RBT

@Max kabul etti; Bence bağlama / çağrı kullanana kadar / uygulamak "Bu" yanlış ya da hiç mantıklı burada bir düzenleme gönderdikten
iono

1
İyileştirme önerileri için teşekkürler. Cevabımı biraz düzenledim. @iono Önerinizde bazı yanlışlıklar vardı, bu yüzden onaylayamadı, ancak yanıtta kendi düzenlemelerimi yaptı. Umarım şimdi daha kapsamlıdır.
CuriousSuperhero

200

BASİT formunda cevap

  • Çağrı işlevi çağırır ve bağımsız değişkenleri tek tek geçirmenizi sağlar.
  • Uygula işlevi çağırır ve bağımsız değişkenleri dizi olarak iletmenizi sağlar.
  • Bind , bu diziyi ve istediğiniz sayıda argümanı iletmenize izin veren yeni bir işlev döndürür.

Uygulama ve Çağrı - Bağlama Örnekleri

Aramak

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

Uygulamak

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

bağlamak

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

Her Biri Ne Zaman Kullanılmalı

Çağrı ve başvuru oldukça değiştirilebilir. Bir diziye mi yoksa virgülle ayrılmış bir argüman listesine göndermenin daha mı kolay olduğuna karar vermeniz yeterlidir.

Aramanın virgül (ayrılmış liste) ve Uygulamanın Dizi için olduğunu hatırlayarak hangisinin hangisi olduğunu her zaman hatırlarım.

Bağlama biraz farklı. Yeni bir işlev döndürür. Ara ve Uygula geçerli işlevi hemen yürütür.

Bağlama birçok şey için harikadır. Yukarıdaki örnekte olduğu gibi işlevleri körüklemek için kullanabiliriz. Basit bir merhaba işlevi alabilir ve bir merhabaJon veya helloKelly'e dönüştürebiliriz. Ayrıca, ne zaman tetikleneceklerini bilmediğimiz ancak hangi bağlamda olmasını istediğimizi bildiğimiz onClick gibi etkinlikler için de kullanabiliriz.

Referans: codeplanet.io


8
Müthiş cevap, eğer benim soru yazım olsaydı, sana onay işareti veriyorum.
AmerllicA

Gelen callve applybir yoksa o uyuyor mu thisyönteminin içine, o zaman bir ilk argüman atayın null?
Daryll Santos

1
@DaryllSantos, MDN'ye göre: thisArg İsteğe bağlı. Bir işleve çağrı için sağlanan bunun değeri. Bunun yöntem tarafından görülen gerçek değer olmayabileceğini unutmayın: yöntem katı olmayan modda bir işlevse, null ve undefined genel nesneyle değiştirilir ve ilkel değerler nesnelere dönüştürülür. Yani bunu işlevde kullanmazsanız önemli değil.
Amit Shah

4
call = = virgül, uygulamak == dizi güzel bir küçük ezberleme
hüneriydi

var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanMükemmel çalışır ve VM128: 4 çıktılar Merhaba Jon Kuperman
Pratik

53

thisİşlevin nasıl çağrıldığından bağımsız olarak değer ayarlanmasına izin verir . Bu, geri aramalarla çalışırken çok kullanışlıdır:

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

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

Aynı sonucu elde etmek için callşu şekilde görünecektir:

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

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

5
.bind()Daha önce gösterdiğin gibi kullanım yanlış. Kullandığınızda fn.bind(obj)başka bir işlev döndürülür (daha önce oluşturduğunuz değil). Ve fonksiyonun thisiçinin değerini değiştirme yeteneği yoktur binded. Çoğunlukla bu geri arama thissigortası için kullanılır . Ama senin örneğinde - sonuçta hiçbir fark yok. Ama fn !== fn.bind(obj);dikkat edin.
ValeriiVasin

@InviS Yorumunuzu anlamıyorum - neden farklı değil?
jantimon

2
Çağrı ve başvurudaki fark. çağrıda argümanları virgülle ayrılmış dizeler olarak geçirirken, uygularken argümanları dizi şeklinde iletebilirsiniz. dinlenme aynı.
Ashish Yadav

virgülle ayrılmış dizeler ?? sadece virgül ayrılmış olarak argümanları geçmek !!
Sudhansu Choudhary

46

multiplicationFonksiyonumuz olduğunu varsayalım

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

Kullanarak bazı standart fonksiyonlar oluşturalım bind

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

Şimdi multiby2 (b) çarpmaya (2, b) eşittir;

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

Bağlamada her iki parametreyi de geçirirsem ne olur?

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

Şimdi getSixAlways () çarpmaya (3,2) eşittir;

getSixAlways();//6

hatta parametre 6'yı döndürür; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Bu yeni bir çarpma işlevi oluşturur ve bunu magicMultiplication öğesine atar.

Oh hayır, çarpma işlevini magicMultiplication içine saklıyoruz.

çağrı magicMultiplicationboş dönerfunction b()

yürütmede iyi çalışıyor magicMultiplication(6,5); //30

Aramaya ve başvurmaya ne dersiniz?

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

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

Basit bir deyişle, bindişlev oluşturur, callve applybuna işlevini yürütür applybeklentiden dizi parametre


Çok iyi açıkladı!
CatalinBerta

3
+1 için "Basit bir deyişle bind,call ve applybuna işlevini yürütür applybeklentiden dizi parametre"
Josh Buchea

32

Her ikisi de Function.prototype.call()ve Function.prototype.apply()verilen thisdeğere sahip bir işlevi çağırır ve o işlevin dönüş değerini döndürür.

Function.prototype.bind(), diğer bir thisdeyişle, belirli bir değere sahip yeni bir işlev oluşturur ve bu işlevi yürütmeden döndürür.

Öyleyse, şuna benzer bir işlev alalım:

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

Şimdi şuna benzer bir nesne alalım:

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

İşlevimizi nesnemize şu şekilde bağlayabiliriz:

Obj.log = logProp.bind(Obj);

Şimdi, Obj.logkodumuzun herhangi bir yerinde çalışabiliriz :

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

Gerçekten ilginç hale geldiği yer, sadece bir değer değil this, aynı zamanda argümanı için de bir değer bağladığınızda prop:

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

Şimdi bunu yapabiliriz:

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

23

bind : İşlevi sağlanan değer ve bağlamla bağlar, ancak işlevi yürütmez. İşlevi yürütmek için işlevi çağırmanız gerekir.

call : İşlevi sağlanan bağlam ve parametre ile yürütür.

Apply : Sağlanan bağlam ve parametreyle işlevi dizi olarak yürütür .


basit ve alçakgönüllü!
Habeeb Perwad

18

İşte biridir iyi makale arasında farkı göstermek için bind(), apply()ve call()aşağıda olarak özetler.

  • bind()bize kolayca bağlanabilir olan özel bir amacı ayarlamak için olanak sağlar , bu , bir işlevi ya da yöntem çağrıldığında.

    // 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() yöntemleri ödünç almamıza izin ver

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

    Bu örnekle ilgili bir sorun showData, carsnesneye yeni bir yöntem eklememiz ve bunu yalnızca bir yöntem ödünç almak için yapmak istemeyebileceğimizden, cars nesnesinin zaten bir özellik veya yöntem adına sahip olabileceğinden showData. Yanlışlıkla üzerine yazmak istemiyoruz. Aşağıda Applyve Callaşağıda tartıştığımız gibi göreceğimiz gibi, Applyveya Callyöntemini kullanarak bir yöntem ödünç almak en iyisidir .

  • bind() bir işlevi köreltmemize izin ver

    Kısmi işlev uygulaması olarak da bilinen İşlev Kıvrımı ,önceden ayarlanmış bazı bağımsız değişkenlerle yeni bir işlev döndüren bir işlevin (bir veya daha fazla bağımsız değişkeni kabul eden) kullanılmasıdır.

    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()Bu greetişlevi köri yapmak için kullanabiliriz

    // 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()veya bu değeri call()ayarlamak için

    apply, callVebind yöntemler hepsi bir yöntemi çağrılırken bu değeri ayarlamak için kullanılır ve bunlar JavaScript kodu kullanımı doğrudan kontrolü ve çok yönlülük sağlamak için biraz farklı şekillerde bunu.

    applyVe callsize fonksiyon parametrelerini geçirmek dışında bu değeri ayarlanırken yöntemleri hemen hemen aynı apply ()şekilde bir dizi Eğer varken, bireysel parametreleri listeler onları geçmek call ()yöntemle.

    İşte bir örnek kullanmaktır callveya applyayarlamak için bu geri arama işlevi.

    // 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
  • applyVeya ile ödünç alma işlevlericall

    • Borrow Array yöntemleri

      Bir array-likenesne oluşturalım ve dizi benzeri nesnemizde çalışmak için bazı dizi yöntemleri ödünç edelim .

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

      Diğer bir yaygın durum argumentsdiziye aşağıdaki gibi dönüştürülmesidir

        // 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"]
    • Diğer yöntemleri ödünç al

      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​
  • Değişken değişken işlevini apply()yürütmek için kullanın

Math.max, Değişken Arity fonksiyonunun bir örneğidir

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

Peki ya bir sayı dizimiz varsa Math.max? Bunu yapamayız:

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

Bu, apply ()yöntemin varyasyon fonksiyonlarını yerine getirmemize yardımcı olduğu yerdir . Yukarıdakilerin yerine, sayı dizisini ( apply () kullanarak :

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

çağrı / uygulama işlevi derhal yürütür:

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

bind işlevi hemen yürütmez, ancak sarılmış uygulama işlevini döndürür (daha sonraki yürütme için):

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

7

Sözdizimi

  • call (thisArg, arg1, arg2, ...)
  • uygulamak (thisArg, argsArray)
  • bind (thisArg [, arg1 [, arg2 [, ...]]])

Buraya

  • thisArg nesnedir
  • argArray bir dizi nesnesidir
  • arg1, arg2, arg3, ... ek argümanlardır

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

Arama, Uygula ve Bağlama arasındaki temel fark şunlardır:

Yürütme bağlamınızın daha sonra resimde görünmesini istiyorsanız, bağlama kullanılır.

Ör:

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

Diyelim ki bu yöntemi başka bir değişkende kullanmak istiyorum

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

Arabanın referansını başka bir değişkende kullanmak için

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

Bağlama fonksiyonunun daha kapsamlı kullanımı hakkında konuşalım

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

func();
// Number: 1

Neden? Şimdi func, Number 1 ile bağlandığından, bu durumda bağlama kullanmazsak, Global Object'i işaret edecektir.

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

func();
// Object

İfadeyi aynı anda yürütmek istediğinizde Ara, Uygula kullanılır.

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

Uygula ve bağla'yı arayın. ve nasıl farklı olduklarını.

Günlük terminolojiyi kullanarak çağrıyı öğrenip uygulayalım.

your_scooter , your_car and your_jetAynı mekanizma (yöntem) ile başlayan üç otomobiliniz var . automobileBir yöntemle bir nesne yarattık 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");
    }
}

Çağrı ve başvurunun ne zaman kullanıldığını anlayalım. Eğer bir mühendis olduğunu varsayalım sağlar ve sahip your_scooter, your_carve your_jethangi bir push_button_engine_start gelmedi ve bir üçüncü tarafı kullanmak isteyenpush_button_engineStart .

Aşağıdaki kod satırlarını çalıştırırsanız, hata verir. NEDEN?

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

Yukarıdaki örnek başarıyla sizin_scooter, otomobiliniz, jetiniz otomobil nesnesinden bir özellik verir.

Daha derine dalalım Burada yukarıdaki kod satırını ayıracağız. automobile.push_button_engineStartkullanılan yöntemi almamıza yardımcı oluyor.

Ayrıca nokta gösterimini kullanarak uygula veya ara özelliğini kullanıyoruz. automobile.push_button_engineStart.apply()

Şimdi uygulayın ve iki parametreyi kabul etmeyi çağırın.

  1. bağlam
  2. argümanlar

Burada bağlamı kodun son satırında ayarladık.

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

Çağrı ve uygulama arasındaki fark , sadece bir virgülle ayrılmış bağımsız değişkenler listesini kabul ederken, uygulamanın bir dizi biçimindeki parametreleri kabul etmesidir.

JS Bind işlevi nedir?

Bir bağlama fonksiyonu temel olarak bir şeyin bağlamını bağlar ve daha sonra onu daha sonraki bir aşamada yürütmek için bir değişkene depolar.

Önceki örneğimizi daha da iyi hale getirelim. Daha önce otomobil nesnesine ait bir yöntem kullandık ve donatmak için kullandık your_car, your_jet and your_scooter. Şimdi push_button_engineStartotomobillerimizi tek tek başlatmak için ayrı bir ayrı vermek istediğimizi hayal edelim .

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

hala memnun değil misiniz?

Gözyaşı damlası olarak netleştirelim. Deneme zamanı. Fonksiyon uygulamasını çağırmak ve uygulamak için geri döneceğiz ve fonksiyonun değerini referans olarak saklamayı deneyeceğiz.

Aşağıdaki deneme başarısız olur çünkü çağrı ve uygulama hemen çağrılır, bu nedenle, bağlama işlevinin şovu çaldığı bir değişkende referans kaydetme aşamasına asla ulaşamayız

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


3

Call: call işlevi çağırır ve bağımsız değişkenleri tek tek geçirmenize olanak tanır

Uygula: Uygula işlevi çağırır ve bağımsız değişkenleri dizi olarak geçirmenize olanak tanır

Bağlama: Bağlama, bu diziye ve istediğiniz sayıda bağımsız değişkeni iletmenize izin veren yeni bir işlev döndürür.

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 (): - Burada işlev bağımsız değişkenlerini dizi biçiminde değil, tek tek geçiriyoruz

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 (): - Burada işlev bağımsız değişkenlerini dizi biçiminde geçiriyoruz

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 Çağrısı ()

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 geçerlidir ()

    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.apply(anotherPerson,[1,2])

** çağrı ve uygulama işlevi, farklı çağrı alma bağımsız değişkenidir ancak aşağıdaki gibi alma dizisi uygular: [1,2,3] **

JavaScript bağlama ()

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

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

1

Düşünün, bağlama mevcut değil. aşağıdaki gibi kolayca inşa edebilirsiniz:

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

Tüm bu yöntemlerin arkasındaki ana kavram Fonksiyon oymasıdır .

İşlev ödünç alma yöntemi, bir yöntemin bir kopyasını oluşturmak ve bunu iki ayrı yerde tutmak zorunda kalmadan bir nesnenin yöntemlerini farklı bir nesne üzerinde kullanmamızı sağlar. Kullanılarak yapılır. aramak() , . uygulamak () veya. hepsi bunu ödünç aldığımız yönteme açıkça ayarlamak için var olan bind ()

  1. Çağrı hemen işlevi çağırır ve bağımsız değişkenleri tek tek geçirmenizi sağlar
  2. Uygula işlevi hemen çağırır ve bağımsız değişkenleri dizi olarak iletmenizi sağlar .
  3. Bind yeni bir işlev döndürür ve bir işlevi çağırarak istediğiniz zaman onu çağırabilir / çağırabilirsiniz.

Aşağıda bu yöntemlerin bir örneği verilmiştir

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

ARAMAK

ilk argüman örneğin çağrı yönteminin içindeki isim her zaman (this) değişkenine bir referanstır ve ikincisi fonksiyon değişkeni olacaktır

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

UYGULAMAK

Apply yöntemi, call yöntemi ile aynıdır, tek fark, işlev argümanlarının Array listesine iletilmesidir

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

BIND

bind yöntemi call ile aynıdır, ancak bind daha sonra çağrılarak kullanılabilen bir işlevi döndürür (hemen çağırmaz)

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

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

printMyNAme () işlevi çağıran işlevdir

aşağıda jsfiddle için bağlantı

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


-1

Bence aynı yerler: hepsi bir fonksiyonun bu değerini değiştirebilir.Farklar arasındaki farklar: bind fonksiyonu sonuç olarak yeni bir fonksiyon döndürecektir; çağrı ve uygulama yöntemleri işlevi hemen yürütür, ancak uygula, bir diziyi params olarak kabul edebilir ve ayrılmış diziyi ayrıştırabilir ve ayrıca bağlama işlevi Currying olabilir.


-3

bind işlevi, örneğin belirli bir içeriğe sahip bir işlev atamak istediğimizde kullanılmalıdır.

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

yukarıdaki örnekte demo.setValue () işlevini çağırır ve this.getValue işlevini doğrudan iletirsek, setTimeout'taki bu pencere nesnesine başvurduğundan demo.setValue işlevini doğrudan çağırmazsa, bu nedenle demo nesnesi içeriğini this.getValue'ya geçirmemiz gerekir bağlama kullanarak işlev. Bu, işlevin yalnızca işlev çağırma işlevini değil demo nesnesinin bağlamıyla geçtiği anlamına gelir.

Umarım anlıyorsunuzdur .

daha fazla bilgi için lütfen ayrıntılı javascript bağlama fonksiyonuna bakınız

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.