Apa gunanya metode JavaScript 'bind'?

651

Apa gunanya bind()dalam JavaScript?

Sandeep Kumar
sumber
8
select = document.querySelector.bind(document)
Kasing
1
^ Dan bagi siapa pun yang bertanya-tanya, alasan yang dibutuhkan adalah karena thiskalau tidak akan merujuk pada window, objek global. Dengan document.querySelector.bind(document), kami memastikan bahwa select's thismengacu pada document, dan tidak window. Seseorang mengoreksi saya jika saya salah paham.
AleksandrH

Jawaban:

614

Bind menciptakan fungsi baru yang akan memaksa bagian thisdalam fungsi menjadi parameter yang diteruskan bind().

Berikut adalah contoh yang menunjukkan cara menggunakan binduntuk melewati metode anggota di sekitar yang memiliki yang benar this:

var myButton = {
  content: 'OK',
  click() {
    console.log(this.content + ' clicked');
  }
};

myButton.click();

var looseClick = myButton.click;
looseClick(); // not bound, 'this' is not myButton - it is the globalThis

var boundClick = myButton.click.bind(myButton);
boundClick(); // bound, 'this' is myButton

Yang mencetak:

OK clicked
undefined clicked
OK clicked

Anda juga dapat menambahkan parameter tambahan setelah parameter 1 ( this) dan bindakan meneruskan nilai-nilai tersebut ke fungsi asli. Parameter tambahan apa pun yang Anda berikan ke fungsi terikat akan diteruskan setelah parameter terikat:

// Example showing binding some parameters
var sum = function(a, b) {
  return a + b;
};

var add5 = sum.bind(null, 5);
console.log(add5(10));

Yang mencetak:

15

Lihat fungsi JavaScript bind untuk info lebih lanjut dan contoh-contoh interaktif.

Pembaruan: ECMAScript 2015 menambahkan dukungan untuk =>fungsi. =>fungsi lebih kompak dan tidak mengubah thispointer dari ruang lingkup pendefinisiannya, jadi Anda mungkin tidak perlu bind()sering menggunakannya . Misalnya, jika Anda ingin fungsi aktif Buttondari contoh pertama untuk menghubungkan clickpanggilan balik ke acara DOM, berikut ini semua cara yang sah untuk melakukan itu:

var myButton = {
  ... // As above
  hookEvent(element) {
    // Use bind() to ensure 'this' is the 'this' inside click()
    element.addEventListener('click', this.click.bind(this));
  }
};

Atau:

var myButton = {
  ... // As above
  hookEvent(element) {
    // Use a new variable for 'this' since 'this' inside the function
    // will not be the 'this' inside hookEvent()
    var me = this;
    element.addEventListener('click', function() { me.click() });
  }
};    

Atau:

var myButton = {
  ... // As above
  hookEvent(element) {
    // => functions do not change 'this', so you can use it directly
    element.addEventListener('click', () => this.click());
  }
};
nkron
sumber
6
Penjelajahan yang bagus, tapi saya kesulitan menemukan contoh di mana saya ingin menggunakan opsi ketiga yang Anda gambarkan alih-alih opsi pertama. Bisakah Anda menggambarkan situasi di mana Anda merasa perlu menggunakan opsi ketiga?
Darryl
5
Saya tidak berpikir saya pernah menggunakan binding selain untuk mengikat 'ini'. Bentuk lain dikenal sebagai Aplikasi Parsial dan cukup umum dalam bahasa fungsional. Saya membayangkan itu termasuk untuk kelengkapan.
nkron
43
Jika ada yang bertanya-tanya mengapa looseClick () tidak terikat ke myButton, itu karena "ini" merujuk ke objek yang memanggil fungsi (looseClick ()). Objek yang memanggil LooseClick () adalah objek global.
pokero
4
@ Darryl - Salah satu alasan mengapa harus lulus parameter dari penangan acara Jika Anda memiliki kode reaksi ini:, var Note = React.createClass({ add: function(text){ ... }, render: function () { return <button onClick={this.add.bind(null, "New Note")}/> } }maka ketika tombol diklik, itu akan melewati teks parameter "Catatan Baru" ke addmetode.
P. Myer Nore
2
"Anda juga dapat menambahkan parameter tambahan setelah parameter 1 dan mengikat akan meneruskan nilai-nilai itu ke fungsi asli sebelum meneruskan parameter tambahan yang Anda berikan ke fungsi terikat:" Kata-kata ini membingungkan.
Ken Ingram
271

Penggunaan paling sederhana bind()adalah membuat fungsi yang, tidak peduli bagaimana namanya, dipanggil dengan thisnilai tertentu .

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

module.getX(); // 81

var getX = module.getX;
getX(); // 9, because in this case, "this" refers to the global object

// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
boundGetX(); // 81

Silakan merujuk tautan ini untuk informasi lebih lanjut

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Renganathan MG
sumber
38
Pengantar terbaik untuk mengikat () yang pernah saya lihat.
thomasfl
3
Jawaban yang bagus, karena contoh Anda tidak memerlukan pengetahuan tentang fitur bahasa (misalnya prototype) yang mungkin baru bagi pemula.
Edward
1
ringkas & sangat jelas!
papigee
172

mengikat memungkinkan-

  • atur nilai "ini" ke objek tertentu. Ini menjadi sangat membantu karena terkadang ini bukan yang dimaksudkan.
  • menggunakan kembali metode
  • kari fungsi

Misalnya, Anda memiliki fungsi untuk mengurangi biaya klub bulanan

function getMonthlyFee(fee){
  var remaining = this.total - fee;
  this.total = remaining;
  return this.name +' remaining balance:'+remaining;
}

Sekarang Anda ingin menggunakan kembali fungsi ini untuk anggota klub yang berbeda. Perhatikan bahwa biaya bulanan akan bervariasi dari anggota ke anggota.

Bayangkan Rachel memiliki saldo 500, dan biaya keanggotaan bulanan 90.

var rachel = {name:'Rachel Green', total:500};

Sekarang, buat fungsi yang dapat digunakan berulang-ulang untuk mengurangi biaya dari akunnya setiap bulan

//bind
var getRachelFee = getMonthlyFee.bind(rachel, 90);
//deduct
getRachelFee();//Rachel Green remaining balance:410
getRachelFee();//Rachel Green remaining balance:320

Sekarang, fungsi getMonthlyFee yang sama dapat digunakan untuk anggota lain dengan biaya keanggotaan yang berbeda. Misalnya, Ross Geller memiliki saldo 250 dan biaya bulanan 25

var ross = {name:'Ross Geller', total:250};
//bind
var getRossFee = getMonthlyFee.bind(ross, 25);
//deduct
getRossFee(); //Ross Geller remaining balance:225
getRossFee(); //Ross Geller remaining balance:200
Jhankar Mahbub
sumber
9
Dalam contoh Anda, saya pikir saya akan cenderung untuk mengatur objek anggota instantiated dengan kata kunci baru di mana setiap anggota memiliki properti / metode mereka sendiri. Maka itu hanya masalah ross.getMonthlyFee (25). Apakah contoh ini hanya untuk mendemonstrasikan penggunaan bind (), atau adakah keuntungan dari pendekatan Anda?
Darryl
suka kari satu fungsi!
Jerry Liu
saya tidak tahu, tetapi saya akan melakukan var getRachelFee = getMonthlyFee (rachel, 90); Dan fungsi akan menjadi fungsi getMonthlyFee (anggota, biaya) {} sesuatu di sepanjang baris.
Miguel
1
@KhanSharp Jawaban Anda benar, tetapi itu adalah referensi Anda untuk serial TV Friends membuat saya berkomentar dan mendukung. Terima kasih atas jawaban Anda 🤗.
Saurabh Lende
79

Dari dokumen MDN pada Function.prototype.bind():

Metode bind () membuat fungsi baru yang, ketika dipanggil, kata kunci ini disetel ke nilai yang disediakan, dengan urutan argumen tertentu sebelum yang disediakan ketika fungsi baru dipanggil.

Jadi, apa artinya itu ?!

Baiklah, 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

Ini berfungsi, karena kita mengikat nilai thiske objek kita Obj.


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

Berbeda dengan dengan Obj.log, kita tidak harus lulus xatau y, karena kita melewati nilai-nilai itu ketika kita melakukan ikatan kita.

John Slegers
sumber
9
Jawaban ini harus mendapatkan lebih banyak cinta. Diterangkan dengan baik.
Chax
Kombinasi yang sangat baik dari tinjauan umum dan contoh spesifik.
Ken Ingram
Di mana tombol yang lurus 100 tegak?
kushalvm
Dengan ini saya juga akan merekomendasikan membaca bagian dokumen MDN dari fungsi yang diterapkan sebagian untuk memahami penggunaan bind "null". Itu harus menutup gerbang untuk sebagian besar penggunaan ikatan. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
kushalvm
23

Variabel memiliki cakupan lokal dan global. Misalkan kita memiliki dua variabel dengan nama yang sama. Satu didefinisikan secara global dan yang lainnya didefinisikan di dalam penutupan fungsi dan kami ingin mendapatkan nilai variabel yang ada di dalam penutupan fungsi. Dalam hal ini kami menggunakan metode bind () ini. Silakan lihat contoh sederhana di bawah ini:

var x = 9; // this refers to global "window" object here in the browser
var person = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

var y = person.getX; // It will return 9, because it will call global value of x(var x=9).

var x2 = y.bind(person); // It will return 81, because it will call local value of x, which is defined in the object called person(x=81).

document.getElementById("demo1").innerHTML = y();
document.getElementById("demo2").innerHTML = x2();
<p id="demo1">0</p>
<p id="demo2">0</p>

krati agarwal
sumber
18

Ringkasan:

The bind()Metode mengambil sebuah objek sebagai argumen pertama dan menciptakan fungsi baru. Ketika fungsi dipanggil nilai thisdalam fungsi tubuh akan menjadi objek yang dilewatkan sebagai argumen dalam bind()fungsi.

Bagaimana this kerjanya di JS pula

Nilai thisdalam javascript tergantung selalu tergantung pada objek apa fungsi dipanggil. Nilai ini selalu mengacu pada objek yang tersisa dari titik dari mana fungsi dipanggil . Dalam hal lingkup global ini adalah window(atau globaldalam nodeJS). Hanya call, applydan binddapat mengubah ikatan ini secara berbeda. Berikut ini contoh untuk menunjukkan cara kerja kata kunci ini:

let obj = {
  prop1: 1,
  func: function () { console.log(this); } 
}

obj.func();   // obj left of the dot so this refers to obj

const customFunc = obj.func;  // we store the function in the customFunc obj

customFunc();  // now the object left of the dot is window, 
               // customFunc() is shorthand for window.customFunc()
               // Therefore window will be logged

Bagaimana bind digunakan?

Bind dapat membantu dalam mengatasi kesulitan dengan thiskata kunci dengan memiliki objek tetap di mana thisakan merujuk. Sebagai contoh:

var name = 'globalName';

const obj = {
  name: 'myName',
  sayName: function () { console.log(this.name);}
}

const say = obj.sayName; // we are merely storing the function the value of this isn't magically transferred

say(); // now because this function is executed in global scope this will refer to the global var

const boundSay = obj.sayName.bind(obj); // now the value of this is bound to the obj object

boundSay();  // Now this will refer to the name in the obj object: 'myName'

Setelah fungsi terikat ke thisnilai tertentu, kita dapat menyebarkannya dan bahkan meletakkannya di properti pada objek lain. Nilai thisakan tetap sama.

Willem van der Veen
sumber
3
Komentar Anda dalam kode Anda tentang objobjek adalah karena titik kiri dan objek windowadalah karena singkatan window.custFunc()dan windowtitik kiri sangat wawasan bagi saya.
nzaleski
12

Saya akan menjelaskan ikatan secara teoritis maupun praktis

bind di javascript adalah metode - Function.prototype.bind. bind adalah metode. Ini disebut prototipe fungsi. Metode ini menciptakan fungsi yang tubuhnya mirip dengan fungsi yang dipanggil tetapi 'ini' mengacu pada parameter pertama yang dilewatkan ke metode bind. Sintaksnya adalah

     var bindedFunc = Func.bind(thisObj,optionsArg1,optionalArg2,optionalArg3,...);

Contoh:--

  var checkRange = function(value){
      if(typeof value !== "number"){
              return false;
      }
      else {
         return value >= this.minimum && value <= this.maximum;
      }
  }

  var range = {minimum:10,maximum:20};

  var boundedFunc = checkRange.bind(range); //bounded Function. this refers to range
  var result = boundedFunc(15); //passing value
  console.log(result) // will give true;
dinesh_malhotra
sumber
Itu pada dasarnya membuat apa pun 'ini' di dalam fungsi menjadi objek apa pun yang Anda lewati, benar?
Harvey Lin
11

Metode bind () membuat instance fungsi baru yang nilainya terikat dengan nilai yang diteruskan ke bind (). Sebagai contoh:

   window.color = "red"; 
   var o = { color: "blue" }; 
   function sayColor(){ 
       alert(this.color); 
   } 
   var objectSayColor = sayColor.bind(o); 
   objectSayColor(); //blue 

Di sini, fungsi baru bernama objectSayColor () dibuat dari sayColor () dengan memanggil bind () dan meneruskan objek o. Fungsi objectSayColor () memiliki nilai ini setara dengan o, jadi memanggil fungsi, bahkan sebagai panggilan global, menghasilkan string "biru" yang ditampilkan.

Referensi: Nicholas C. Zakas - JAVASCRIPT® PROFESIONAL UNTUK PEMBANGUN WEB

Otti
sumber
contoh singkat dan singkat
Ahmad Sharif
9

Membuat Fungsi baru dengan Mengikat Argumen ke Nilai

The bindMetode menciptakan fungsi baru dari fungsi lain dengan satu atau lebih argumen terikat nilai-nilai tertentu, termasuk implisit thisargumen.

Aplikasi Parsial

Ini adalah contoh aplikasi parsial . Biasanya kami menyediakan fungsi dengan semua argumennya yang menghasilkan nilai. Ini dikenal sebagai aplikasi fungsi. Kami menerapkan fungsi untuk argumennya.

Fungsi Orde Tinggi (HOF)

Aplikasi parsial adalah contoh dari fungsi urutan yang lebih tinggi (HOF) karena menghasilkan fungsi baru dengan jumlah argumen yang lebih sedikit.

Mengikat Banyak Argumen

Anda dapat menggunakan binduntuk mengubah fungsi dengan banyak argumen menjadi fungsi baru.

function multiply(x, y) { 
    return x * y; 
}

let multiplyBy10 = multiply.bind(null, 10);
console.log(multiplyBy10(5));

Konversi dari Metode Instance ke Fungsi Statis

Dalam kasus penggunaan yang paling umum, ketika dipanggil dengan satu argumen bindmetode akan membuat fungsi baru yang memiliki thisnilai terikat ke nilai tertentu. Akibatnya ini mengubah metode contoh ke metode statis.

function Multiplier(factor) { 
    this.factor = factor;
}

Multiplier.prototype.multiply = function(x) { 
    return this.factor * x; 
}

function ApplyFunction(func, value) {
    return func(value);
}

var mul = new Multiplier(5);

// Produces garbage (NaN) because multiplying "undefined" by 10
console.log(ApplyFunction(mul.multiply, 10));

// Produces expected result: 50
console.log(ApplyFunction(mul.multiply.bind(mul), 10));

Menerapkan CallBack Stateful

Contoh berikut menunjukkan bagaimana menggunakan pengikatan thisdapat mengaktifkan metode objek untuk bertindak sebagai panggilan balik yang dapat dengan mudah memperbarui keadaan suatu objek.

function ButtonPressedLogger()
{
   this.count = 0;
   this.onPressed = function() {
      this.count++;
      console.log("pressed a button " + this.count + " times");
   }
   for (let d of document.getElementsByTagName("button"))
      d.onclick = this.onPressed.bind(this);
}

new ButtonPressedLogger();      
<button>press me</button>
<button>no press me</button>

cdiggins
sumber
6

Seperti yang disebutkan, Function.bind()memungkinkan Anda menentukan konteks yang akan dieksekusi oleh fungsi tersebut (yaitu, ia memungkinkan Anda meneruskan objek apa yang thisakan diselesaikan oleh kata kunci di tubuh fungsi.

Beberapa metode API toolkit analog yang melakukan layanan serupa:

jQuery.proxy ()

Dojo.hitch ()

mtyson
sumber
3
/**
 * Bind is a method inherited from Function.prototype same like call and apply
 * It basically helps to bind a function to an object's context during initialisation 
 * 
 * */

window.myname = "Jineesh";  
var foo = function(){ 
  return this.myname;
};

//IE < 8 has issues with this, supported in ecmascript 5
var obj = { 
    myname : "John", 
    fn:foo.bind(window)// binds to window object
}; 
console.log( obj.fn() ); // Returns Jineesh
Jineesh
sumber
3

Pertimbangkan Program Sederhana yang tercantum di bawah ini,

//we create object user
let User = { name: 'Justin' };

//a Hello Function is created to Alert the object User 
function Hello() {
  alert(this.name);
}

//since there the value of this is lost we need to bind user to use this keyword
let user = Hello.bind(User);
user();

//we create an instance to refer the this keyword (this.name);
Astaga, kebaikan Chi
sumber
2

Fungsi bind menciptakan fungsi baru dengan fungsi tubuh yang sama dengan fungsi yang dipanggil. Disebut dengan argumen ini. Mengapa kita menggunakan bind fun. : ketika setiap kali instance baru dibuat dan kami harus menggunakan instance awal pertama maka kami menggunakan bind fun. Kami tidak dapat mengesampingkan bind fun. hanya menyimpan objek awal kelas.

setInterval(this.animate_to.bind(this), 1000/this.difference);
pengguna2485861
sumber
0

Penggunaan lain adalah bahwa Anda dapat melewatkan fungsi terikat sebagai argumen ke fungsi lain yang beroperasi di bawah konteks eksekusi lain.

var name = "sample";
function sample(){
  console.log(this.name);
}
var cb = sample.bind(this);

function somefunction(cb){
  //other code
  cb();
}
somefunction.call({}, cb);
Amar T
sumber
0

Contoh sederhana

function lol(text) {
    console.log(this.name, text);
}

lol(); // undefined undefined
lol('first'); // undefined first
lol.call({name: 'karl'}); // karl undefined
lol.call({name: 'karl'}, 'second'); // karl second
lol.apply({name: 'meg'}); // meg undefined
lol.apply({name: 'meg'}, ['third']); // meg third
const newLol = lol.bind({name: 'bob'});
newLol(); // bob undefined
newLol('fourth'); // bob fourth
K - Toksisitas dalam SO meningkat.
sumber
0

Metode Bind

Implementasi bind mungkin terlihat seperti ini:

Function.prototype.bind = function () {
  const self = this;
  const args = [...arguments];
  const context = args.shift();

  return function () {
    return self.apply(context, args.concat([...arguments]));
  };
};

Fungsi bind dapat mengambil sejumlah argumen dan mengembalikan fungsi baru .

Fungsi baru akan memanggil fungsi asli menggunakan Function.prototype.applymetode JS .
The applymetode akan menggunakan argumen pertama diteruskan ke fungsi target sebagai konteksnya ( this), dan argumen array kedua dari applymetode akan menjadi kombinasi dari sisa argumen dari fungsi target, concat dengan argumen yang digunakan untuk memanggil kembali para fungsi (dalam urutan itu).

Contoh dapat terlihat seperti ini:

function Fruit(emoji) {
  this.emoji = emoji;
}

Fruit.prototype.show = function () {
  console.log(this.emoji);
};

const apple = new Fruit('🍎');
const orange = new Fruit('🍊');

apple.show();  // 🍎
orange.show(); // 🍊

const fruit1 = apple.show;
const fruit2 = apple.show.bind();
const fruit3 = apple.show.bind(apple);
const fruit4 = apple.show.bind(orange);

fruit1(); // undefined
fruit2(); // undefined
fruit3(); // 🍎
fruit4(); // 🍊

Lior Elrom
sumber
0

Penjelasan Sederhana:

bind () membuat fungsi baru, referensi baru pada fungsi yang dikembalikan kepada Anda.

Pada parameter setelah kata kunci ini, Anda memasukkan parameter yang ingin Anda konfigurasikan sebelumnya. Sebenarnya tidak langsung dieksekusi, hanya persiapan untuk eksekusi.

Anda dapat mengonfigurasikan sebanyak mungkin parameter yang Anda inginkan.

Contoh sederhana untuk memahami ikatan:

function calculate(operation) {
  if (operation === 'ADD') {
   alert('The Operation is Addition');
  } else if (operation === 'SUBTRACT') {
   alert('The Operation is Subtraction');
  }
}

addBtn.addEventListener('click', calculate.bind(this, 'ADD'));
subtractBtn.addEventListener('click', calculate.bind(this, 'SUBTRACT'));
Shivu
sumber
-1

bind adalah fungsi yang tersedia dalam prototipe skrip java, seperti namanya bind digunakan untuk mengikat pemanggilan fungsi Anda ke konteks mana pun yang Anda hadapi misalnya::

    var rateOfInterest='4%';
    var axisBank=
    {
    rateOfInterest:'10%',
    getRateOfInterest:function()
    {
    return this.rateOfInterest;
    }
    }
    axisBank.getRateOfInterest() //'10%' 


    let knowAxisBankInterest=axisBank.getRateOfInterest // when you want to assign the function call to a varaible we use this syntax
    knowAxisBankInterest(); // you will get output as '4%' here by default the function is called wrt global context

let knowExactAxisBankInterest=knowAxisBankInterest.bind(axisBank);     //so here we need bind function call  to its local context


    knowExactAxisBankInterest() // '10%' 

Thara
sumber