Panggilan Javascript () & apply () vs bind ()?

794

Saya sudah tahu itu applydan callfungsi serupa yang mengatur this(konteks fungsi).

Perbedaannya adalah dengan cara kami mengirim argumen (manual vs array)

Pertanyaan:

Tetapi kapan saya harus menggunakan bind()metode ini?

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

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

jsbin

Royi Namir
sumber
9
Bukan salah Anda jika ada pengguna yang melihat poin reputasi OP sebelum memposting jawaban atau peningkatan :)
Gabriel Llamas
54
panggil dan terapkan panggilan fungsi sementara mengikat membuat fungsi. Meskipun dengancall()Anda melewati argumen secara individual danapply()sebagai array argumen. Untuk perincian lebih lanjut, lihat dokumentasi tertaut yang seharusnya dapat menjawab pertanyaan Anda sepenuhnya.
Tidak
3
kind of weird there is not an existing question about this :Mengenai itu. Itu mungkin karena bind()ditambahkan setelah dua lainnya sudah ada di JavaScript 1.8.5 - ECMA-262, edisi ke-5. Sementara call()dan apply()telah ada sejak JavaScript 1.3 - ECMA-262 3rd Edition. SO memiliki pertanyaan pada mereka seperti: apa-perbedaan-antara-panggilan-dan-berlaku . Aku hanya menebak-nebak ketika aku bertanya-tanya sendiri.
Tidak
apakah Anda memerlukan metode ini (panggilan, terapkan, ikat) di sini ?? tanpa ini, Anda juga dapat memanggil metode dan ini hanya akan menunjuk ke objek
Mahi
checkout tautannya - techyaura-blogs.blogspot.com/2020/05/...
techyaura

Jawaban:

131

Saya membuat perbandingan ini antara objek fungsi, panggilan fungsi, call/applydan bindbeberapa waktu yang lalu:

masukkan deskripsi gambar di sini

.bindmemungkinkan Anda untuk mengatur thisnilai sekarang sambil memungkinkan Anda untuk mengeksekusi fungsi di masa depan , karena mengembalikan objek fungsi baru.

Felix Kling
sumber
779

Gunakan .bind()ketika Anda ingin fungsi itu nanti dipanggil dengan konteks tertentu, berguna dalam acara. Gunakan .call()atau.apply() ketika Anda ingin menjalankan fungsi dengan segera, dan ubah konteksnya.

Panggil / terapkan panggil fungsi segera, padahal bind mengembalikan fungsi yang, ketika nanti dieksekusi, akan memiliki konteks yang benar untuk memanggil fungsi asli. Dengan cara ini Anda dapat mempertahankan konteks dalam panggilan balik dan acara async.

Saya sering melakukan ini:

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

Saya menggunakannya secara luas di Node.js untuk panggilan balik async yang ingin saya sampaikan metode anggota, tetapi masih ingin konteksnya menjadi contoh yang memulai tindakan async.

Implementasi bind yang sederhana dan naif akan seperti:

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

Ada lebih dari itu (seperti melewati argumen lain), tetapi Anda dapat membaca lebih lanjut tentang hal itu dan melihat implementasi nyata di MDN .

Semoga ini membantu.

Chad
sumber
2
@RoyiNamir yang benar, Anda dapat menggunakan fungsi "terikat" yang dikembalikan nanti, dan konteksnya akan dipertahankan.
Chad
5
Itulah yang bindkembali.
Chad
@RoyiNamir Mengedit jawaban saya
Chad
4
Anda juga dapat menggunakan bind untuk sebagian, meneruskan argumen sebelum fungsi dipanggil.
Andrew Kirkegaard
1
Anda hanya menerapkan bind, tidak ada perbedaan. Either way Anda hanya membungkusnya dalam penutupan yang memiliki akses ke variabel lingkup yang menyimpan konteks. Kode Anda pada dasarnya adalah polyfill yang saya posting.
Chad
446

Mereka semua melampirkan ini ke dalam fungsi (atau objek) dan perbedaannya ada pada pemanggilan fungsi (lihat di bawah).

panggilan melampirkan ini ke dalam fungsi dan menjalankan fungsi segera:

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 menempelkan ini ke dalam fungsi dan harus dipanggil secara terpisah seperti ini:

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"

atau seperti ini:

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

berlaku mirip dengan panggilan kecuali bahwa itu mengambil objek seperti array bukannya daftar argumen keluar satu per satu:

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
sumber
1
Apakah ini berarti perbedaannya adalah bahwa Bind adalah Penutupan?
Gregory R.
Anda baru saja mengajari saya tentang fitur argumen yang digunakan di dalam suatu fungsi melalui cuplikan kode Anda. Dianjurkan untuk menyebutkan "use strict"untuk menghindari mengesampingkan kata kunci yang dipesan tersebut. +1.
RBT
@ Max setuju; Saya telah mengirimkan hasil edit di mana "ini" salah atau tidak masuk akal sampai kami menggunakan bind / call / apply
iono
1
Terima kasih atas saran peningkatannya. Saya sedikit mengedit jawaban saya. @iono Saran Anda memiliki beberapa ketidakakuratan sehingga tidak dapat menyetujuinya, tetapi lakukan pengeditan saya sendiri dalam jawabannya. Semoga sekarang lebih komprehensif.
CuriousSuperhero
200

Jawab dalam bentuk SIMPLEST

  • Panggilan memanggil fungsi dan memungkinkan Anda untuk menyampaikan argumen satu per satu.
  • Terapkan memanggil fungsi dan memungkinkan Anda untuk mengirimkan argumen sebagai array.
  • Bind mengembalikan fungsi baru, memungkinkan Anda untuk mengirimkan array ini dan sejumlah argumen.

Terapkan vs. Panggilan vs. Contoh Bind

Panggilan

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

Menerapkan

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

Mengikat

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

Kapan Harus Menggunakan Masing-masing

Panggilan dan terapkan sangat bisa dipertukarkan. Putuskan saja apakah lebih mudah untuk mengirim dalam array atau daftar argumen yang dipisahkan koma.

Saya selalu ingat yang mana dengan mengingat bahwa Panggilan adalah untuk koma (daftar terpisah) dan Terapkan untuk Array.

Bind sedikit berbeda. Ini mengembalikan fungsi baru. Panggilan dan Terapkan segera jalankan fungsi saat ini.

Bind sangat bagus untuk banyak hal. Kita bisa menggunakannya untuk menjelajah fungsi seperti pada contoh di atas. Kita dapat mengambil fungsi halo sederhana dan mengubahnya menjadi helloJon atau helloKelly. Kami juga dapat menggunakannya untuk acara seperti diKlik di mana kami tidak tahu kapan mereka akan dipecat tetapi kami tahu konteks apa yang kami inginkan.

Referensi: codeplanet.io

Amit Shah
sumber
8
Jawaban yang luar biasa, jika itu adalah posting pertanyaan saya, saya memberi Anda tanda centang ANDA.
AmerllicA
Di calldan apply, apakah itu mengikuti bahwa jika Anda tidak memiliki thisdi dalam metode, maka Anda akan menetapkan argumen pertama sebagai null?
Daryll Santos
1
@DaryllSantos, Menurut MDN: thisArg Opsional. Nilai ini disediakan untuk panggilan ke suatu fungsi. Perhatikan bahwa ini mungkin bukan nilai aktual yang dilihat oleh metode: jika metode ini adalah fungsi dalam mode non-ketat, null dan undefined akan diganti dengan objek global dan nilai-nilai primitif akan dikonversi menjadi objek. Jadi, jika Anda tidak menggunakan ini dalam fungsi itu tidak masalah.
Amit Shah
4
call = = koma, terapkan == array adalah trik menghafal kecil yang bagus
drlff
var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon KupermanBekerja dengan sangat baik dan menghasilkan VM128: 4 Halo Jon Kuperman
Pratik
53

Ini memungkinkan untuk mengatur nilai untuk thisindependen dari bagaimana fungsi dipanggil. Ini sangat berguna saat bekerja dengan callback:

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

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

Untuk mencapai hasil yang sama dengan callakan terlihat seperti ini:

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

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
Jimimon
sumber
5
Penggunaan .bind()seperti yang Anda tunjukkan sebelumnya tidak benar. Ketika Anda menggunakan fn.bind(obj)fungsi lain akan dikembalikan (bukan yang Anda buat sebelumnya). Dan tidak ada kemampuan untuk mengubah nilai thisdi dalam bindedfungsi. Sebagian besar ini digunakan untuk thisasuransi callback . Tetapi dalam contoh Anda - tidak ada perbedaan dalam hasilnya. Tapi fn !== fn.bind(obj);perhatikan itu.
ValeriiVasin
@InviS Saya tidak mengerti komentar Anda - mengapa tidak ada yang berbeda?
jantimon
2
Perbedaan dalam panggilan dan berlaku adalah. dalam panggilan Anda meneruskan argumen sebagai string yang dipisahkan koma, sementara dalam menerapkan Anda dapat meneruskan argumen dalam bentuk array. sisanya sama.
Ashish Yadav
string yang dipisahkan koma ?? cukup berikan argumen sebagai dipisahkan koma !!
Sudhansu Choudhary
46

Anggaplah kita memiliki multiplicationfungsi

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

Mari kita membuat beberapa fungsi standar menggunakan bind

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

Sekarang multiby2 (b) sama dengan perkalian (2, b);

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

Bagaimana jika saya melewati kedua parameter dalam bind

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

Sekarang getSixAlways () sama dengan multiplikasi (3,2);

getSixAlways();//6

bahkan melewati parameter mengembalikan 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

Ini membuat fungsi multiplikasi baru dan menetapkannya ke magicMultiplication.

Oh tidak, kami menyembunyikan fungsi multiplikasi ke dalam magicMultiplication.

panggilan magicMultiplicationmengembalikan tanda kosongfunction b()

pada eksekusi itu berfungsi dengan baik magicMultiplication(6,5); //30

Bagaimana dengan menelepon dan melamar?

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

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

Dengan kata-kata sederhana, bindbuat fungsi, calldan applyjalankan fungsi sementara applymengharapkan parameter dalam array

tk120404
sumber
Dijelaskan dengan sangat baik!
CatalinBerta
3
+1 untuk "Dengan kata sederhana, bindmembuat fungsi, calldan applymengeksekusi fungsi sementara applymengharapkan parameter dalam array"
Josh Buchea
32

Keduanya Function.prototype.call()dan Function.prototype.apply()memanggil fungsi dengan thisnilai yang diberikan , dan mengembalikan nilai balik dari fungsi itu.

Function.prototype.bind(), di sisi lain, membuat fungsi baru dengan thisnilai yang diberikan , dan mengembalikan fungsi itu tanpa menjalankannya.

Jadi, mari kita fungsi yang terlihat seperti ini:

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

Sekarang, mari kita ambil objek yang terlihat seperti ini:

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

Kita dapat mengikat fungsi kita ke objek kita seperti ini:

Obj.log = logProp.bind(Obj);

Sekarang, kita dapat menjalankan Obj.logdi mana saja dalam kode kita:

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

Di mana itu benar-benar menarik, adalah ketika Anda tidak hanya mengikat nilai this, tetapi juga untuk argumennya prop:

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

Kita sekarang dapat melakukan ini:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
John Slegers
sumber
23

bind : Ini mengikat fungsi dengan nilai dan konteks yang disediakan tetapi tidak menjalankan fungsi. Untuk menjalankan fungsi, Anda perlu memanggil fungsi.

panggilan : Menjalankan fungsi dengan konteks dan parameter yang disediakan.

apply : Ini mengeksekusi fungsi dengan konteks dan parameter yang disediakan sebagai array .

Siddhartha
sumber
sederhana dan rendah hati!
Habeeb Perwad
18

Berikut adalah satu artikel bagus untuk menggambarkan perbedaan di antara bind(), apply()dan call(), merangkumnya seperti di bawah ini.

  • bind()memungkinkan kita untuk dengan mudah mengatur objek spesifik mana yang akan terikat dengan ini ketika suatu fungsi atau metode dipanggil.

    // 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() izinkan kami untuk meminjam metode

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

    Satu masalah dengan contoh ini adalah bahwa kami menambahkan metode baru showDatapada carsobjek dan kami mungkin tidak ingin melakukannya hanya dengan meminjam metode karena objek mobil mungkin sudah memiliki properti atau nama metode showData. Kami tidak ingin menimpanya secara tidak sengaja. Seperti yang akan kita lihat dalam diskusi kita tentang Applydan di Callbawah ini, yang terbaik adalah meminjam metode menggunakan metode Applyatau Call.

  • bind() memungkinkan kita untuk menjelajah suatu fungsi

    Function Currying , juga dikenal sebagai aplikasi fungsi parsial , adalah penggunaan fungsi (yang menerima satu atau lebih argumen) yang mengembalikan fungsi baru dengan beberapa argumen yang telah ditetapkan.

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

    Kita dapat menggunakannya bind()untuk menjelajah greetfungsi ini

    // 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()atau call()untuk mengatur ini nilai

    The apply, call, danbind metode semuanya digunakan untuk menetapkan nilai ini ketika memanggil metode, dan mereka melakukannya dengan cara yang sedikit berbeda untuk memungkinkan penggunaan kontrol langsung dan keserbagunaan dalam kode JavaScript kami.

    Metode applydan callhampir identik ketika mengatur nilai ini kecuali bahwa Anda melewatkan parameter fungsi apply ()sebagai array , sementara Anda harus mendaftar parameter secara individual untuk meneruskannya ke call ()metode.

    Berikut adalah salah satu contoh untuk menggunakan callatau applymengatur ini dalam fungsi panggilan balik.

    // 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
  • Pinjam fungsi dengan applyataucall

    • Metode Array Pinjam

      Mari kita membuat array-likeobjek dan meminjam beberapa metode array untuk beroperasi pada objek seperti array kita.

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

      Kasus umum lainnya adalah konversi argumentske array sebagai berikut

        // 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"]
    • Pinjam metode lain

      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​
  • Gunakan apply()untuk menjalankan fungsi variabel-arity

Ini Math.maxadalah salah satu contoh fungsi variabel-arity,

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

Tetapi bagaimana jika kita memiliki sejumlah angka untuk diteruskan Math.max? Kami tidak bisa melakukan ini:

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

Di sinilah apply ()metode ini membantu kami menjalankan fungsi variadic . Alih-alih di atas, kita harus melewati array angka menggunakan apply () dengan demikian:

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
sumber
8

segera panggil / terapkan fungsi eksekusi:

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

bind tidak menjalankan fungsi dengan segera, tetapi mengembalikan fungsi apply yang dibungkus (untuk eksekusi nanti):

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}
Eldiyar Talantbek
sumber
7

Sintaksis

  • panggilan (thisArg, arg1, arg2, ...)
  • berlaku (thisArg, argsArray)
  • bind (thisArg [, arg1 [, arg2 [, ...]]])

Sini

  • thisArg adalah objek
  • argArray adalah objek array
  • arg1, arg2, arg3, ... adalah argumen tambahan

function printBye(message1, message2){
    console.log(message1 + " " + this.name + " "+ message2);
}

var par01 = { name:"John" };
var msgArray = ["Bye", "Never come again..."];

printBye.call(par01, "Bye", "Never come again...");
//Bye John Never come again...

printBye.call(par01, msgArray);
//Bye,Never come again... John undefined

//so call() doesn't work with array and better with comma seperated parameters 

//printBye.apply(par01, "Bye", "Never come again...");//Error

printBye.apply(par01, msgArray);
//Bye John Never come again...

var func1 = printBye.bind(par01, "Bye", "Never come again...");
func1();//Bye John Never come again...

var func2 = printBye.bind(par01, msgArray);
func2();//Bye,Never come again... John undefined
//so bind() doesn't work with array and better with comma seperated parameters

Shiljo Paulson
sumber
6

Perbedaan mendasar antara Panggilan, Terapkan, dan Bind adalah:

Bind akan digunakan jika Anda ingin konteks eksekusi Anda muncul nanti dalam gambar.

Ex:

var car = { 
  registrationNumber: "007",
  brand: "Mercedes",

  displayDetails: function(ownerName){
    console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
  }
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**

Katakanlah saya ingin menggunakan metode ini di beberapa variabel lain

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

Untuk menggunakan referensi mobil di beberapa variabel lain yang harus Anda gunakan

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

Mari kita bicara tentang penggunaan fungsi bind yang lebih luas

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

func();
// Number: 1

Mengapa? Karena sekarang func terikat dengan Nomor 1, jika kita tidak menggunakan mengikat dalam kasus itu akan mengarah ke Objek Global.

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

func();
// Object

Panggil, Terapkan digunakan ketika Anda ingin menjalankan pernyataan pada saat yang sama.

var Name = { 
    work: "SSE",
    age: "25"
}

function displayDetails(ownerName) {
    console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE

In apply we pass the array
displayDetails.call(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE
Nishant Parashar
sumber
4

Panggilan berlaku dan ikat. dan bagaimana mereka berbeda.

Mari belajar panggilan dan terapkan menggunakan terminologi harian apa pun.

Anda memiliki tiga mobil your_scooter , your_car and your_jetyang dimulai dengan mekanisme (metode) yang sama. Kami membuat objek automobiledengan metode 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");
    }
}

Mari kita mengerti kapan panggilan dan melamar digunakan. Mari kita anggap bahwa Anda adalah seorang insinyur dan Anda miliki your_scooter, your_cardan your_jetyang tidak datang dengan push_button_engine_start dan Anda ingin menggunakan pihak ketiga push_button_engineStart.

Jika Anda menjalankan baris kode berikut, mereka akan memberikan kesalahan. MENGAPA?

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

Jadi contoh di atas berhasil memberikan your_scooter, your_car, your_jet fitur dari objek mobil.

Mari selami lebih dalam Di sini kita akan membagi baris kode di atas. automobile.push_button_engineStartmembantu kami mendapatkan metode yang digunakan.

Selanjutnya kami menggunakan apply atau call menggunakan notasi titik. automobile.push_button_engineStart.apply()

Sekarang terapkan dan panggil terima dua parameter.

  1. konteks
  2. argumen

Jadi di sini kita mengatur konteks di baris terakhir kode.

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

Perbedaan antara panggilan dan berlaku adalah hanya berlaku menerima parameter dalam bentuk array sementara panggilan hanya dapat menerima daftar argumen yang dipisahkan koma.

apa fungsi JS Bind?

Fungsi bind pada dasarnya yang mengikat konteks sesuatu dan kemudian menyimpannya ke dalam variabel untuk dieksekusi pada tahap selanjutnya.

Mari kita membuat contoh kita sebelumnya menjadi lebih baik. Sebelumnya kami menggunakan metode milik objek mobil dan menggunakannya untuk melengkapi your_car, your_jet and your_scooter. Sekarang mari kita bayangkan kita ingin memberikan yang terpisah push_button_engineStartsecara terpisah untuk memulai mobil kita sendiri pada setiap tahap selanjutnya dari eksekusi yang kita inginkan.

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

masih belum puas?

Mari kita perjelas sebagai tetesan air mata. Waktunya bereksperimen. Kami akan kembali untuk memanggil dan menerapkan aplikasi fungsi dan mencoba menyimpan nilai fungsi sebagai referensi.

Eksperimen di bawah ini gagal karena panggilan dan penerapan segera dipanggil, oleh karena itu, kami tidak pernah sampai ke tahap menyimpan referensi dalam variabel yang merupakan fungsi mengikat mencuri acara

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

Sagar Munjal
sumber
3

Panggilan: panggilan memanggil fungsi dan memungkinkan Anda untuk melewati argumen satu per satu

Terapkan: Terapkan menerapkan fungsi dan memungkinkan Anda untuk melewati argumen sebagai array

Bind: Bind mengembalikan fungsi baru, memungkinkan Anda untuk meneruskan dalam array ini dan sejumlah argumen.

var person1 = {firstName: 'Raju', lastName: 'king'};
var person2 = {firstName: 'chandu', lastName: 'shekar'};

function greet(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
function greet2(greeting) {
        console.log( 'Hello ' + this.firstName + ' ' + this.lastName);
    }


greet.call(person1, 'Hello'); // Hello Raju king
greet.call(person2, 'Hello'); // Hello chandu shekar



greet.apply(person1, ['Hello']); // Hello Raju king
greet.apply(person2, ['Hello']); // Hello chandu shekar

var greetRaju = greet2.bind(person1);
var greetChandu = greet2.bind(person2);

greetRaju(); // Hello Raju king
greetChandu(); // Hello chandu shekar

raju poloju
sumber
2

call (): - Di sini kita melewati argumen fungsi satu per satu, bukan dalam format array

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 (): - Di sini kita memberikan argumen fungsi dalam format array

var obj = {name: "Raushan"};

var cal = function(a,b,c) {
    return this.name +" you got " + a+b+c;
};

var arr =[1,2,3];  // array format for function arguments
console.log(cal.apply(obj, arr)); 

bind (): -

       var obj = {name: "Raushan"};

       var cal = function(a,b,c) {
            return this.name +" you got " + a+b+c;
       };

       var calc = cal.bind(obj);
       console.log(calc(2,3,4));
Raushan
sumber
2

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

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

** fungsi panggil dan terapkan adalah perbedaan panggil bawa argumen terpisah tetapi terapkan take array seperti: [1,2,3] **

Binding JavaScript ()

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

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()
Shuvro
sumber
1

Bayangkan, bind tidak tersedia. Anda dapat dengan mudah membangunnya sebagai berikut:

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

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

bindHelper(arguments);
Philippe Oceangermanique
sumber
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
sumber
0

Konsep utama di balik semua metode ini adalah Function burrowing .

Fungsi meminjam memungkinkan kita untuk menggunakan metode dari satu objek pada objek yang berbeda tanpa harus membuat salinan dari metode itu dan memeliharanya di dua tempat yang terpisah. Ini dicapai melalui penggunaan. panggilan (),. berlaku (), atau. bind (), yang semuanya ada untuk secara eksplisit mengatur ini pada metode yang kita pinjam

  1. Panggilan memanggil fungsi segera dan memungkinkan Anda untuk menyampaikan argumen satu per satu
  2. Terapkan segera memanggil fungsi dan memungkinkan Anda untuk menyampaikan argumen sebagai array .
  3. Bind mengembalikan fungsi baru, dan Anda dapat memohon / memanggilnya kapan saja Anda inginkan dengan menjalankan fungsi.

Di bawah ini adalah contoh dari semua metode ini

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

PANGGILAN

argumen pertama misalnya nama di dalam metode panggilan selalu referensi ke variabel (ini) dan yang terakhir akan menjadi variabel fungsi

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

MENERAPKAN

menerapkan metode sama dengan metode panggilan satu-satunya perbedaan adalah bahwa, argumen fungsi dilewatkan dalam daftar Array

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

MENGIKAT

Metode bind sama dengan panggilan kecuali itu, bind mengembalikan fungsi yang dapat digunakan nanti dengan memanggilnya (tidak langsung memanggilnya)

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

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

printMyNAme () adalah fungsi yang memanggil fungsi

di bawah ini adalah tautan untuk jsfiddle

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

Arham Chowdhury
sumber
-1

Saya pikir tempat yang sama adalah: semuanya dapat mengubah nilai fungsi ini. Perbedaannya adalah: fungsi bind akan mengembalikan fungsi baru sebagai hasilnya; metode panggilan dan terapkan akan menjalankan fungsi dengan segera, tetapi berlaku dapat menerima array sebagai params, dan itu akan menguraikan array yang dipisahkan. Dan juga, fungsi bind bisa menjadi Currying.

Xin Tao
sumber
-3

fungsi bind harus digunakan ketika kita ingin menetapkan fungsi dengan konteks tertentu misalnya.

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

dalam contoh di atas jika kita memanggil fungsi demo.setValue () dan meneruskan fungsi ini.getValue secara langsung, maka ia tidak memanggil fungsi demo.setValue secara langsung karena ini dalam setTimeout merujuk ke objek jendela sehingga kita perlu meneruskan konteks objek demo ke this.getValue berfungsi menggunakan bind. itu berarti kita hanya melewati fungsi dengan konteks objek demo bukan fungsi panggilan aktif.

Semoga kamu mengerti.

untuk informasi lebih lanjut silakan lihat fungsi bav javascript tahu secara detail

pengguna7339156
sumber