This (bind)

First of all this is global! It exists from the top of your javascript code. All you are doing is binding the object onto the method which will be referenced inside the method as "this", as when you call a method directly it doesn't know in which object it is contained. You have to tell it!

There are 4 ways of binding.

  • Apply
  • Call
  • Bind
  • Method
  • New binding

Quick "this" rule

var Person = function(name, age) {
  return {
    name: name,
    age: age,
    sayName: function() { // public
      console.log(this.name);
    },
    mother: { // public
      name: 'Stacey',
      sayName: function() {
        console.log(this.name)
      }
    }
  }
}
 
var John = Person('John', 42); // create new object without prototype
John.sayName(); // John (john is this)
John.mother.sayName(); // Marie (mother is this)
 
/* THIS RULE
1. With this, always pay attention to where the function is invoked 
2. Look to if there's anything to the left to the dot dot
*/

Apply and Call

Both the same, just one you pass a parameter, the other an array.
You will use Call() or Apply() if you immediately need to invoke the function called. Unlike bind() were you're just passing through the this object.

Borrow methods

var obj = {
   name: 'John Smith',
   greet: function() {
 
   }
}
 
obj.greet();
obj.greet.call({ name: 'John Carroll' }, param1, param2); // puts the object through as "this", just connects it
obj.greet.apply({ name: 'John Carroll' }, [param1, param2]); // puts the object through as "this", just connects it
// Example
 
var obj = {
  name: "James"
}
 
var user = {
  name: "John",
  getName: function(greeting) {
     console.log(greeting + ' my name is ' + this.name);
  }
}
 
// Bind and evoke method
user.getName('Hello'); // user object is binded to getName() as "this" automatically......translates as user.getName.bind(user);
 
// Call binds an object and invokes the method
user.getName.call(obj, "Hello"); // obj is binded as this (parameter)
 
// Apply binds an object and invokes the method
user.getName.call(obj, ["Hello"]); // obj is binded as this (array)
 
// Bind binds the object but doesn't invoke any method
var message = user.getName.bind(obj); 
message.getName(); // invoke it
 
// New binding
var user = new user;
// Example
 
var user = {
  name: 'John',
  getName: function() {
     return this.name;
  }
}
 
user.getName() // user object is binded to getName() as "this"......translates as user.getName.bind(user); bind(user) is a hard bind.

http://2ality.com/2013/06/auto-binding.html

var user = {
  name: 'John',
  describe: function() {
    'use strict'; 
    return "I’m " + this.name; 
  }
};
 
var john = user.describe; // normal function - the object in which it sits (user) isn't binded. Loses connection and lexical scope, and only thinks it exists on its own.
console.log(john); // I'm undefined
 
var john = user.describe(); // user binded automatically when using () , so this translates as bind **user** to **describe** please ie. user.describe.bind(user); So now it will use that object
console.log(john);
 
// Hard bind it 
var user = user.describe; // just a function returned so we need to tell it what object to use 
var displayName = user.describe.bind(user); // uses user.prototype.bind(user)
console.log( displayName() ); // I'm John

Another example of binding this

let user = {
  age: "34",
  getName: function() {
    console.log("My name is " + this.age);
  }
}
 
user.getName(); // My name is John, as () bind user automatically ie. user.getName.bind(user); 
 
var john = user.getName; // only returns the function 
/* 
Translates as...
 
var john = function() {
  console.log("My name is " + this.age);
}
*/
john(); // My name is undefined

Another example…

var age = 9;
var user = {
    age: 81,
    getAge: function () {
        return this.age;
    }
}; 
 
console.log( user.getAge() ); // 81 - Why? Because the function parentheses () binds user 
 
var getAge = user.getAge; // nothing binded it's just a raw function
console.log( getAge() ); // 9, because in this case, "this" refers to the global object
 
// How to bind
var age = getAge.bind(user); // manually bind user
console.log( age() ); // 81

Use var self = this; or bind()

For better readability using var self = this is just an identifier. Bit hacky. As this if isn't passed through its lexical

ES6 solves this by making inheriting this throughout it's lexical scope…YEY! So any inner functions of a function can use this

Proper way of doing it (non-ES6)

var obj = {
      count = 0,
      cool: function cool() {
 
         if(this.count < 1) {
             setTimeout( function timer() {
                this.count++;
 
             }.bind( this ), 100);
         }
      }
}

Real World

let user = {
  age: "35",
  getName: function() {
    console.log("My name is " + this.age);
  }, 
  updateDiv: function() {
     document.getElementById("demo").innerHTML = this.age;
  }
}
 
var button = document.getElementById("myBtn");
button.addEventListener("click", user.updateDiv()); // or user.updateDiv.bind(user)

Implicit Binding (that's what it's called)

// Default binding. Think of 'this' as the default binding.
// Global object
 
// This comment is in the global object
 
function foo() {
  console.log(this.a);
}
 
var a = 5; // global object property and synonamous with global object properties of the same name
 
var obj = { 
  a: 2,
  foo: foo  
}; 
 
// Lost binding
var foo = obj.foo; 
 
foo();  // 5 : just a function 
 
// Implicit binding
obj.foo(); // 2 : passes obj as this

Implicit binding example 2

var User = function(obj) {
  obj.sayName = function() {
    console.log(this.name);
  }
}
 
var me = {
  name: 'John'
}
 
var her = {
  name: 'Kate'
}
 
User(me); // links all methods and stuff to me object
User(her); // links all methods and stuff to her object
 
me.sayName(); // John
her.sayName(); // Kate

Hard Binding

See page 19 of Kyles books on This and Prototypes. A hard bind is

function foo() {
  console.log( this.a );
}
 
var obj = {
  a: 2
}
 
var bar = function() {
  foo.call( obj );
}
 
bar(); // 2
bar.call(window) // 2 - this isn't overridden
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License