Javascript?: call(), apply() and bind()

Javascript: call(), apply() and bind()

“this” refresher

In Object Oriented JS we learned that in JS, everything is an object. Because everything is an object, we came to understand that we could set and access additional properties to functions.

Setting properties to a function and additional methods via the prototype is super awesome … but how do we access them?!??!

We were introduced to the this keyword. We learned that every function gets this property automatically. So at this point in time, if we were to create a mental model of our function execution context( I am not the only one who does this!… right?!?!), it would look something like this:

It took us a little while to get comfortable with the this keyword, but once we did we began to realize how useful it is. this is used inside a function, and will always refer to a single object — the object that invokes (calls) the function where “this” is used.

But life isn’t perfect. Sometimes, we lose our this reference. When that happens, we end up using confusing hacks to save our reference to this. Check out this confusing hack from our localStorage exercise:


So why did I need to save a this reference? Because inside deleteBtn.addEventListener, this refers to the deleteBtn object. This is unfortunate. Is there a better solution?

call(), apply() and bind() — a new hope

Up until now we have treated functions as objects that are composed of a name (optional, can also be an anonymous function) and the code it executes when it is invoked. But that isn’t the entire truth. As a truth loving person, I must let you know that a function actually looks closer to the following image:

What is this??????? Don’t worry! I will now walk through these 3 similar methods that appear on every function with examples. Rejoice!

bind()

The official docs say: The bind() method creates a new function that, when called, has its this keyword set to the provided value. (It actually talks about even more stuff, but we’ll leave that for another time :) )

This is extremely powerful. It let’s us explicitly define the value of this when calling a function. Let’s look at cooooode:

var player = {
    firstname: 'Mohamed',
    lastname: 'Salah ',
    getPlayerName: function() {
        var fullname = this.firstname + ' ' + this.lastname;
        return fullname;
    }
};

var playerName = function() {
    console.log(this.getPlayerName() + 'I choose you!');
};

var logPlayer = playerName.bind(player); // creates new object and binds player. 'this' of player === player now

logPlayer(); // 'Mohamed Salah I choose you!'


Let’s break it down. When we use the bind() method:

  1. the JS engine is creating a new playerName instance and binding player as its this variable. It is important to understand that it copies the playerName function.
  2. After creating a copy of the playerName function it is able to call logPlayer(), although it wasn’t on the player object initially. It will now recognizes its properties (Mohamed and Salah) and its methods.

And the cool thing is, after we bind() a value we can use the function just like it was any other normal function. We could even update the function to accept parameters, and pass them like so:

var player = {
    firstname: 'Mohamed',
    lastname: 'Salah ',
    getPlayerName: function() {
        var fullname = this.firstname + ' ' + this.lastname;
        return fullname;
    }
};

var playerName = function(clubName, date) {
    console.log(this.getPlayerName() + 'I choose you!');
    console.log(date + this.getPlayerName() + 'agreed a transfer to' + clubName
 );

};
var logPlayer = playerName.bind(player); // creates new object and binds player. 'this' of player === player now

playerName('Liverpool', 'On 22 June 2017'); // On 22 June 2017 Mohamed Salah agreed a transfer to Liverpool.




call(), apply()

The official docs for call() say: The call() method calls a function with a given this value and arguments provided individually.

What that means, is that we can call any function, and explicitly specify what this should reference within the calling function. Really similar to the bind() method! This can definitely save us from writing hacky code (even though we are all still hackerzzz).

The main differences between bind() and call() is that the call()method:

  1. Accepts additional parameters as well
  2. Executes the function it was called upon right away.
  3. The call() method does not make a copy of the function it is being called on.

call() and apply() serve the exact same purpose. The only difference between how they work is that call() expects all parameters to be passed in individually, whereas apply() expects an array of all of our parameters. Example:

var player = {
    firstname: 'Mohamed',
    lastname: 'Salah ',
    getPlayerName: function() {
        var fullname = this.firstname + ' ' + this.lastname;
        return fullname;
    }
};

var playerName = function(clubName, date) {
    console.log(date + this.getPlayerName() + 'agreed a transfer to' + clubName
 );
};


playerName.call(player,'Liverpool', 'On 22 June 2017'); // On 22 June 2017 Mohamed Salah agreed a transfer to Liverpool.
playerName.apply(player,['Liverpool', 'On 22 June 2017']); // On 22 June 2017 Mohamed Salah agreed a transfer to Liverpool.




These built in methods, that exist on every JS function can be very useful. Even if you do not end up using them in your day to day programming, you will still run into it often when reading other peoples code.

Dennys Jose M.

Software Developer | Senior Front-End (JavaScript ES6, React, Next, Redux, Angular, Node) | Jr CyberSecurity (Owasp, Ethical Hacking)

6 年

Versus no! serían más bien sus diferencias cada una aplica a una situación diferente las 3 son necesarias según el caso ninguna es mejor que la otra

回复
Asma BEN GHARBI

Solutions Architect at Sopra HR Software | TOGAF? 9 | Scrum Master?| AWS Solutions Architect ?| LPI DevOps? | RHCSA ?

6 年

Wonderful contribution

要查看或添加评论,请登录

Radhouen Assakra的更多文章

  • Ansible Vs Terraform

    Ansible Vs Terraform

    Ansible vs Terraform: Which Tool to Choose for Infrastructure Automation? Infrastructure automation is an essential…

  • Deploy Angular using Docker , Ansible and Packer

    Deploy Angular using Docker , Ansible and Packer

    By default to create a Docker image we can start by creating a Dockerfile, after with docker build we can create an…

  • Reusable Angular components

    Reusable Angular components

    To reuse where it is possible is a natural instinct in all aspects of life. The idea that something can serve other…

  • Angular 7 with Azure DevOps Build Pipeline

    Angular 7 with Azure DevOps Build Pipeline

    Angular 7 is a very useful JavaScript framework for building applications. Being able to build these projects on Azure…

    2 条评论
  • Run Golang in production

    Run Golang in production

    Deploying Go Apps with Systemd : Create Rest Full API with Go: package main import (…

    2 条评论
  • Continuous Integration - Jenkins vs Travis-CI

    Continuous Integration - Jenkins vs Travis-CI

    What is CI? Continuous integration is a software development method where members of the team can integrate their work…

  • 10 Best Jenkins Plugins For DevOps

    10 Best Jenkins Plugins For DevOps

    Jenkins is one of the best continuous integration (CI) servers you can find. The fact that it is one of the most aged…

  • Jenkins, InfluxDB, Docker and Grafana

    Jenkins, InfluxDB, Docker and Grafana

    I said in the last article that I'll speak about systems with docker in the next article, but I choose today this topic…

  • Systemd : Basic commands

    Systemd : Basic commands

    Introduction Systemd is the system manager that replaces upstart and its predecessor ( system V scripts ) from Ubuntu…

  • INFRASTRUCTURE AS CODE with Packer

    INFRASTRUCTURE AS CODE with Packer

    HashiCorp Packer is easy to use and automates the creation of any type of machine image. It embraces modern…

    1 条评论

社区洞察

其他会员也浏览了