Basic Rule
Implicit binding applies when we use a function and invoke it as a method of an object. In that case, the this
keyword points to the object on which the method was invoked.
In the following examples you will notice that the invocation of getName
was done using the object person
and thats what made the this
keyword point to the person
object.
var person = {firstName: "meher",getName: function () {console.log(this.firstName)},}person.getName() // outputs meher
Function Outside the Method
Also, it does not matter whether the function was defined within the object or not. Look at the below example, the function's definition location doesn't matter at all. But because the function again invoked using the person
object, the this
keyword understand the context and points the to the person
object.
function getName() {console.log(this.firstName)}var person = {firstName: "meher",getName,}person.getName() // outputs meher
Now, you can notice that because function location doesn't matter, we can use this property to our advantage and create a reusable function(s) that can be run on different objects and return different result. Imagine, if we had employee
object somewhere in the codebase and a person
object. Both object can reuse the firstName
function.
When Implicit Binding Fails
If you store the function reference in a variable and then invoke the function later. The implicit binding is lost.
var person = {firstName: "meher",getName: function () {console.log(this.firstName)},}var fn = person.getNamefn() // looks up globally?
Callbacks
In the case of the callbacks, the general rule these days is that whatever is on the left side, which doesn't work . See why:
function getName() {console.log(this.firstName)}var person = {firstName: "meher",getName,}function displayFirstName(cb) {cb()}displayFirstName(person.getName)
Even when implicit-lost context is passed, the global issue is still raised.
function getName() {console.log(this.firstName)}var person = {firstName: "meher",getName,}setTimeout(person.getName, 1000)// An implementation similar to this could be found in a library or native API:function setTimeout(fn, delay) {fn()}