Context binding when a function is called in Javascript



Often, we could the code :

this.that = this;

or

this.self = this;

But what represent self and that ?
Contrary to this which refers the object in the current context, self and that are not Javascript reserved words.
These are convention variable names used by Javascript developers to store in the context of an object.
But why is it needed ? thisis not always enough ? Unfortunately, no because Javascript has some awkward design principles and that issue is a part of them.
We will study here problematic cases and how to bypass Javascript language limitations.

Here an account variable representing an object with properties and functions.
An account identified by a number has a balance and one function to credit the balance :

var account = {
        	number : 101010,
        	balance : 0,
 
        	credit : function (amount){
        		this.balance += amount;			
        		return account;
        	}        		
}

Now, we will see that the credit() function has different behavior according to the context it is called.

The easy case that works

1) account context

Calling explicitly a function from the account object reference.

account.credit(50); 
RENDER account.balance

    Result = ?

Problematic cases where the context is not which is expected

2) global context because the function is called from a variable

Calling a function from a variable referencing the credit() function.

var f = account.credit; f(50);
RENDER account.balance

    Result = ?

3) global context because the function is transmitted as a parameter

Calling a function from a parameter referencing the credit() function.
Here a function to log and execute any function

  function logAndExecute (fx, args){
    fx(args);
  }

Call it :

logAndExecute(50);
RENDER account.balance

    Result = ?

A one-shot solution to solve the problem

4) account context with the apply() function

Calling a function from a variable referencing the credit() function by using apply() function.

var f = account.credit; 
	f.apply(account,[50]);
RENDER account.balance

    Result = ?

A more solid solution to solve the problem : we tackle the cause of the problem

5) account context by modifying account object declaration

Calling apply() function at each time is a overhead. So, we will introduce a constructor which when it is called saves the context of this in the that variable (generally named that or self):

       var Account = function() {
              this.number = 101010;
              this.balance = 0;
              this.that = this;
 
              this.credit = function credit (amount){
                that.balance += amount;     
                return account;
              },
 
              this.clear = function(){
                that.balance = 0;
              }
 
              return that;
      }

Now, check if with that new account object, the used context is which expected.

Calling a function from a variable referencing the credit() function.

 var accountObj = Account(); var f = accountObj.credit; f(50);
RENDER accountObj.balance

    Result = ?

Ce contenu a été publié dans Non classé. Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *