Enable Dark Mode!
By: Yassir Irfan

How to Use the Call, Apply, & Bind Functions in Javascript


The flexible language JavaScript provides a number of effective ways to work with function contexts and pass parameters. Of these, `call()`, `apply()`, and `bind()} are three of the most useful functions, each with a specific function.

Understanding the Methods

1. call() Method

The `call()` method executes a function, explicitly setting the context (`this`) and providing arguments individually. For instance:

function greet() {
    console.log(`Hello, ${this.name}!`);
const person = { name: 'John Doe' };
greet.call(person); // Output: Hello, John Doe!

This method allows you to invoke a function with a specific `this` context, beneficial for one-time invocations.

1.1 Example for call() from Odoo

slice.call(arguments, 2)))

Here's what's happening:

* Arguments is an array-like object available inside every function that contains the arguments passed to that function.

* .call() is used here to invoke the slice method. The reason for using .call() with slice is that arguments is not a true array, but rather an array-like object, so it doesn't have all the array methods directly.

* By using .call() with slice, it's borrowing the slice method from the Array.prototype and applying it to the arguments object, allowing it to work on arguments as if it were an array.

* slice.call(arguments, 2) is essentially taking a portion of the arguments object starting from index 2 and converting it into a proper array. It effectively extracts the arguments starting from the third position (index 2) and converts them into an array.

2. apply() Method

Like `call()`, `apply()` runs a function with a defined context (`this}), but it takes parameters in the form of an object that resembles an array. For instance:

function greet(message) {
    console.log(`${message}, ${this.name}!`);
const person = { name: 'Jane Doe' };
greet.apply(person, ['Hi']); // Output: Hi, Jane Doe!

Use `apply()` when passing an array of arguments to a function.

2.1 Example for apply() from Odoo

var array_splice = Array.prototype.splice;
return array_splice.apply(this, [
                    start === void 0 ? 0 : start,
                    deleteCount === void 0 ? (this.length - start) : deleteCount

Here's what's happening:

* The first argument (this) inside apply() refers to the array on which the splice method is being called.

* The second argument is an array that contains the modified start and deleteCount values.

* The third argument is created using slice.call(arguments, 2), which collects all the additional arguments passed to the overridden splice method after start and deleteCount. These arguments are gathered starting from the third position (2) of the arguments object and converted into an array using slice.

* The .concat() method concatenates the modified start and deleteCount values array with the array containing additional arguments (if any), creating a single array of arguments to be passed to array_splice.

* Execution: The apply() method is used here to invoke array_splice with the modified start, deleteCount, and additional arguments in the context of the current array. This essentially mimics the behavior of the original splice method, allowing for modified parameter handling while ensuring that the overridden splice function behaves similarly to the native one.

3. bind() Method

In contrast to `call()` and `apply()`, `bind()` creates a new function with a fixed {this} context and delays the execution of the original function. Here's an example:

function greet() {
    console.log(`Greetings, ${this.name}!`);
const person = { name: 'Alice' };
const greetPerson = greet.bind(person);
greetPerson(); // Output: Greetings, Alice!

When building functions with a preset `this` value, this method works perfectly and allows for numerous invocations.

3.1 Example for bind() from Odoo

const node = getCurrent();
let render = batchedRenderFunctions.get(node);
render = batched(node.render.bind(node, false));

Here's what's happening:

* .bind() is applied to the node.render function.

* Node is passed as the first argument to .bind(). This sets the context (this value) for the function when it's invoked.

* False is passed as an argument after node. These arguments will be prepended to the arguments list when the bound function is invoked.

* So, the resulting bound function created by .bind() will be a version of node.render where: this will always refer to the node when the bound function is called.

* False will be passed as the first argument to node.render every time the bound function is invoked.

* This technique allows for the creation of a specific function that retains a particular context (this value) and preset arguments, ensuring consistent behavior when the function is subsequently called.

Advantages and Use Cases

- `call()` and `apply()`: These are suitable for single function invocations, allowing specific `this` context and easy argument passing.

- `bind()`: It excels in scenarios where you need a function with a fixed `this` context for multiple invocations.

Practical Applications

- Event Handling: Utilize these methods to manage event listeners with defined contexts.  

- Function Composition: Create composed functions with specified contexts for seamless execution.  

- Object-Oriented Programming: Maintain precise contexts within classes and methods for enhanced readability and functionality.

In conclusion, understanding and employing `call()`, `apply()`, and `bind()` empower developers to wield JavaScript functions effectively, ensuring accurate context management and streamlined argument passing in diverse programming scenarios. If you want to know more about functions in JavaScript, you can refer to our previous blogs.

If you need any assistance in odoo, we are online, please chat with us.


Leave a comment




Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635



Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.



Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message