Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use .bind() in JS

Tags:

javascript

There is a ton of blogs and posts about how to use bind() and how it's different than call() and apply(), but there is very little examples to when or why should I use bind()

I found many of the examples given are very uncommon occurrences such as this:

"use strict";

function Person(firstName, lastName){
  this.firstName = firstName
  this.lastName = lastName
}

Person.prototype.say = function(message){
  return '[' + this + ']: ' + this.firstName + ' ' + this.lastName + ' said: "' + message + '"'
}

Person.prototype.toString = function(){
  return '[Person]'
}

moe = new Person("Mo", "El")


func = moe.say.bind(moe)

console.log(func("asdasda"))

I don't know when there is a time I want to make a function equal to some other variable and use that variable instead of the original function, let alone that variable is equal the binding of an instance of the Person object.

Any good examples?

like image 982
Mohamed El Mahallawy Avatar asked Oct 21 '14 00:10

Mohamed El Mahallawy


People also ask

When would you use the bind function in JavaScript?

Function Borrowing With the bind() method, an object can borrow a method from another object. The example below creates 2 objects (person and member).

What is the purpose of a bind?

BIND is an open source system free to download and use, offered under the Mozilla Public License. BIND can be used to run a caching DNS server or an authoritative name server, and provides features like load balancing, notify, dynamic update, split DNS, DNSSEC, IPv6, and more.

Where can I use BIND?

bind() is used when you need to pass a callback (e.g. some sort of function reference), but you want the caller to call your function with a specific this value.

Why we use BIND In react JS?

The bind() is an inbuilt method in React that is used to pass the data as an argument to the function of a class based component.


1 Answers

In a nutshell, .bind() returns a new function that when called will call the original function with a specific this value and (optionally) some new arguments preprended to the argument list.

.bind() is used when you need to pass a callback (e.g. some sort of function reference), but you want the caller to call your function with a specific this value. This is most common when your function is actually a method and you want the this value set to be the a specific object so the method will operate on that specific object . If you don't use .bind() in those cases, then the this value will be determined by the caller (not you) and if the caller doesn't set it specifically, it will end up being the global object or (in strict mode) undefined. If what you were passing was a method that relies on a specific value of this in order to do its job, it would not work properly with the wrong this value.

So, if you want to control the value of this when your callback is called, you can use .bind(). Internally, .bind() just creates a small stub function that just remembers the this value you pass it and calls your function with .apply() to set the this value. .bind() is not magic as it can be done manually too.

.bind() also has the capability to add extra arguments to the function so, if you want to add arguments beyond what the normal caller of the callback uses, you can specify those with .bind() too. It creates a stub function that will add these extra arguments and set the this value.


Let's say you have your Person object and you want to hook a button up to the .say() method for a particular Person object.

<button id="talk">Talk</button>

And, if you tried this javascript:

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", bob.say);

What you would find is that the say() method is called, but it would be missing two things. It would be missing the right this reference (which would be set to the button object because that's how addEventListener calls its callbacks) and it would be missing the argument that say(message) expects.

So, you could solve this yourself with your own stub function that calls bob.say() with all the right arguments:

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", function(e) {
    bob.say("Hello");
});

Or, you could use .bind():

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", bob.say.bind(bob, "Hello"));

There is no magic in .bind(). It can be entirely simulated in javascript. In fact, here's a polyfill for it from MDN:

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

This may look more complicated than it is because of all the error checking, but it's really just return a new function that combines two sets of arguments and then calls the original function with a specific this value.

like image 127
jfriend00 Avatar answered Oct 19 '22 01:10

jfriend00