• 18-19 College Green, Dublin 2
  • 01 685 9088
  • info@cunninghamwebsolutions.com
  • cunninghamwebsolutions
    Cunningham Web Solutions
    • HomeHome
    • About UsAbout Us
    • Our ServicesOur Services
      • Web Design
      • Digital Marketing
      • SEO Services
      • E-commerce Websites
      • Website Redevelopment
      • Social Media Services
    • Digital MarketingDigital Marketing
      • Adwords
      • Social Media Services
      • Email Marketing
      • Display Advertising
      • Remarketing
    • PortfolioPortfolio
    • FAQ’sFAQ’s
    • BlogBlog
    • Contact UsContact Us
    MENU CLOSE back  
    • Home
    • About Us
    • Our Services
      • back
      • Web Design
      • Digital Marketing
      • SEO Services
      • E-commerce Websites
      • Website Redevelopment
      • Social Media Services
    • Digital Marketing
      • back
      • Adwords
      • Social Media Services
      • Email Marketing
      • Display Advertising
      • Remarketing
    • Portfolio
    • FAQ’s
    • Blog
    • Contact Us

    Taming this In JavaScript With Bind Operator

    You are here:
    1. Home
    2. Web Design
    3. Taming this In JavaScript With Bind Operator
    Thumbnail for 21695

    Taming this In JavaScript With Bind Operator

    Taming this In JavaScript With Bind Operator

    Willian Martins

    2018-10-05T14:20:22+02:00
    2018-10-05T12:29:03+00:00

    Do you want to discover the next exciting JavaScript features that you didn’t even know you needed? In this article, I will introduce one of these proposals that if accepted may change the way you write code the same way the spread operator did.

    However, here’s a small disclaimer: This feature is under development and discussion. The goal here is to add some hype around it and create awareness of the hard work that TC39 is doing to find consensus, fix all the syntax and semantics issues and have it shipped with the next releases of ECMAScript. If you have any concerns, comments or desire to express your support, please go to the TC39 proposals repository, add a star to this feature to show your support, open an issue to voice your concerns and get involved.

    But before, I want to ask a simple (but tricky) question:

    What is this?

    In ECMAScript, this has a different semantic than this in many other programming languages, where this often refers to the lexical scope. In general, this behaves differently in the global scope, within a function, in non-strict mode and strict mode. Let’s break this behavior down into small examples.

    Getting workflow just right ain’t an easy task. So are proper estimates. Or alignment among different departments. That’s why we’ve set up “this-is-how-I-work”-sessions — with smart cookies sharing what works well for them. A part of the Smashing Membership, of course.

    Explore Smashing Membership ↬

    this In The Global Scope

    What is the value of this in this example?

    console.info(this);

    At the global scope, this refers to the global object, like the window in the browser, self on web workers and the module.exports object in NodeJS.

    this In The Function Scope

    At the function scope, this behaves depending on how the function is called, and this aspect makes it tricky to predict its value. We can understand it better by checking the following examples:

    What Is The Value Of this Here?

    function foo() {
      return this;
    }
    
    console.info(this);
    

    Inside a function, this starts to have an interesting behavior since its value depends on how the function is called. In the example above, this still refers to the global scope, with one difference. In NodeJs, this will point to the global object instead of module.exports.

    Setting A Value Into this:

    function foo() {
      this.bar = 'baz';
      return this;
    }
    
    console.info(foo());
    console.info(new foo());
    

    Setting a value into this sets the value into the current context. The example above logs the global scope with the property bar with the value baz in the first console.info, but it logs only { bar: ‘baz' } in the second console.info. It happens because the new operator among other things bounds the value of this to the newly created object.

    This Keyword In The Strict Mode

    In strict mode, the this variable doesn’t carry the value of the context implicitly, this means if its context isn’t set, the value of this is default to undefined as shown in the following snippet.

    function foo() {
      "use strict";
      return this;
    }
    
    console.info(foo()); //undefined
    

    To set the context of this in strict mode you can set the function as member of an object, use new operator, Function.prototype.call(), Function.prototype.apply() or Function.prototype.bind() methods for example.

    function foo() {
      "use strict";
      return this;
    }
    
    var a = { foo };
    
    foo(); // undefined
    a.foo(); // { foo: ƒunction }
    new foo(); // Object foo {}
    foo.call(this); // Window / Global Object
    foo.apply(this); // Window / Global Object
    foo.bind(this)(); // Window / Global Object
    

    Making this Variable Predictable

    At this point, you may realize that the value of this in ECMAScript is quite tricky to predict. To demonstrate the available techniques to make it predictable, I’d like to present the following example that mimics a common use case of this.

    <button id="button">🐱 🐾</button>
    <script>
      class MeowctComponent {
        constructor() {
          this.paw = document.getElementById('button');
        }
    
        meow() {
          console.info('🐱 on this: ', this.paw);
        }
      }
    
      const cat = new MeowctComponent();
      cat.paw.addEventListener('click', cat.meow);
    </script>
    

    In the example above, I created a MeowctComponent, which has only one property paw that points to the button element and one method called meow that should print the paw instance property into the console.

    The tricky part is that the meow method is executed only when the button is clicked, and because of that, this has the button tag as context, and since the button tag does not have any paw property, it logs the undefined value into the console. Tricky, isn’t it?

    To fix this specific behavior we can leverage on the Function.prototype.bind() method to explicitly bind this to the cat instance, like in the following example:

    <button id="button">Meow</button>
    <script>
      class MeowctComponent {
        constructor() {
          this.paw = document.getElementById('button');
        }
    
        meow() {
          console.info('🐱 on this: ', this.paw);
        }
      }
    
      const cat = new MeowctComponent();
      cat.paw.addEventListener('click', cat.meow.bind(cat));
    </script>
    

    The method .bind() returns a new permanently bound function to the first given parameter, which is the context. Now, because we bound the cat.meow method to the cat instance, this.paw inside the meow method correctly points to the button element.

    As an alternative to the Function.prototype.bind() method, we can use the arrow function to achieve the same result. It keeps the value of the lexical this of the surrounding context and dispenses the need to bind the context explicitly, like in the next example:

    <button id="button">🐱 Meow</button>
    <script>
      class MeowctComponent {
        constructor() {
          this.paw = document.getElementById('button');
        }
    
        meow() {
          console.info('🐱 on this: ', this.paw);
        }
      }
    
      const cat = new MeowctComponent();
      cat.paw.addEventListener('click', () => cat.meow());
    </script>
    

    Although arrow functions solve the majority of use cases where we need to bind the lexical this explicitly, we still have two use cases for which the use of the explicit bind is needed.

    Calling A Known Function Using this To Provide Context:

    let hasOwnProp = Object.prototype.hasOwnProperty;
    let obj = Object.create(null);
    
    obj.hasOwnProperty('x') // Type Error...
    
    hasOwnProp.call(obj, "x"); //false
    
    obj.x = 100;
    
    hasOwnProp.call(obj, "x"); // true
    

    Let’s suppose for any reason we have this obj object that doesn’t extend Object.prototype but we need to check if obj has an x property by using the hasOwnProperty method from Object.prototype. To achieve that, we have to use the call method and explicitly pass obj as the first parameter to make it work as expected, which appears not to be so idiomatic.

    Extracting A Method

    The second case can be spotted when we need to extract a method from an object like in our MeowctComponent example:

    <button id="button">🐱 🐾</button>
    <script>
      class MeowctComponent {
        constructor() {
          this.paw = document.getElementById('button');
        }
    
        meow() {
          console.info('🐱 on this: ', this.paw);
        }
      }
    
      const cat = new MeowctComponent();
      cat.paw.addEventListener('click', cat.meow.bind(cat));
    </script>
    

    These use cases are the baseline problem that the bind operator tries to solve.

    The Bind Operator ::

    The Bind operator consists of an introduction of a new operator :: (double colon), which acts as syntax sugar for the previous two use cases. It comes in two formats: binary and unary.

    In its binary form, the bind operator creates a function with its left side is bound to this of the right side, like in the following example:

    let hasOwnProp = Object.prototype.hasOwnProperty;
    let obj = Object.create(null);
    
    obj.hasOwnProperty('x') // Type Error...
    
    obj::hasOwnProp("x"); //false
    
    obj.x = 100;
    
    obj::hasOwnProp("x"); // true
    

    That looks more natural, doesn’t it?

    In its unary form, the operator creates a function bound to the base of the provided reference as a value for this variable, like in the following example:

    ...
    cat.paw.addEventListener('click', ::cat.meow);
    // which desugars to
    cat.paw.addEventListener('click', cat.meow.bind(cat));
    ...
    

    What’s so cool about the bind operator is the fact that it opens up new opportunities for creating virtual methods, as in this example of lib for iterable.

    import { map, takeWhile, forEach } from "iterlib";
    
    getPlayers()
      ::map(x => x.character())
      ::takeWhile(x => x.strength > 100)
      ::forEach(x => console.log(x));
    

    It’s super useful because the developer doesn’t need to download the whole lib to do small stuff, which reduces the amount of imported JavaScript. Besides, it makes those kinds of libs easier to extend.

    How To Develop Using Bind Operator

    To keep the example simple, let’s suppose we need to create a math module which the developer can chain the operations to form an math expression that, given a number as an entry it could make all calculations into a pipeline. The code to achieve this is simple and could be written as the following.

    function plus(x) {
      return this + x;
    }
    
    function minus(x) {
      return this - x;
    }
    
    function times(x) {
      return this * x;
    }
    
    function div(x) {
      return this / x;
    }
    

    As you can spot in the example above, we expect to have the value as a context and we use this to make the calculation, so then using the bind operator, we could make an expression like the following:

    1::plus(2)::times(4)::div(3)::minus(1); // returns 3
    

    Which is equivalent to:

    minus.call(div.call(times.call(plus.call(1, 2), 4), 3), 1);
    

    The first snippet looks more idiomatic, isn’t?

    Going a little further, we can use it to convert a temperature from Celsius to Fahrenheit, this can be accomplished by the following function expression:

    const toFahrenheit = x => x::times(9)::div(5)::plus(32);
    console.info(toFahrenheit(20)); // 68
    

    So far, we demonstrate how create functions to interact with the values, but what about extending the object with virtual methods? We can do new stream compositions mixing built-in methods with custom ones. To demonstrate it, we can compose string methods with custom ones. First, let’s check the module with the custom methods with its implementation.

    function capitalize() {
      return this.replace(/(?:^|s)S/g, a => a.toUpperCase());
    }
    
    function doubleSay() {
      return `${this} ${this}`;
    }
    
    function exclamation() {
      return `${this}!`;
    }
    

    With this module in place we can do cool things like the following:

    const { trim, padEnd } = String.prototype;
    
    console.info(
      '   hello world   '
        ::trim()
        ::capitalize()
        ::doubleSay()
        ::exclamation()
        ::padEnd(30)
    );
    
    // "Hello World Hello World!      "
    

    In the example above, you can spot that I extracted two methods from the String.prototype, trim() and padEnd(). Since these methods are extracted, I can use them to compose my stream of methods alongside with my virtual methods capitalize(), doubleSay() and exclamation(). This aspect is what makes bind operator so exciting and promising.

    Advantages And Disadvantages Of Bind Operator

    As you may realize at this point, there are some aspects that Bind Operator shines. Those are the following:

    • It covers the only two missing use cases that explicit bind is necessary;
    • It makes easy to make this variable to be predictable;
    • It adds a new way to extend functionality by using virtual methods;
    • It helps to extend built-in objects without extending the prototype chain. Do you remember Smoosh Gate?

    In the other side, to compose functions with bind operator you need to rely on this to be bound, that can lead to some issues like in this example:

    const plus = (x) => this + x;
    
    console.info(1::plus(1));
    // "[object Window]1"
    

    As it becomes clear in the example above, it’s not possible to compose arrow function with bind operator, since it’s not possible to bind this to an arrow function. Sometimes users don’t want to rely on this to be bound to compose their behavior through a function chain, which could be a problem if you only use bind operator to achieve this.

    Another issue that is often said is the possible syntax overload that the bind operator can bring which can be a problem to onboard newcomers to the language. Realizing that a specific operator works in binary and unary form is tricky as well. One possible solution for this is to introduce the binary form to the language separately of the unary form. So once the binary form is integrated to the language, the committee can reassess if the unary form is still necessary. Meanwhile, users can get used to the binary form, and the syntax overload could potentially be mitigated.

    Conclusion

    Predict the value of this in JavaScript is trick. The language has some rules to explain how the context is assigned to this, but in the daily basis we want to make this value predictable. The Function.prototype.bind() method and arrow functions help us to make the value of this predictable. The bind operator comes to play to cover the two use cases that we still need to explicitly bind this.

    The advent of bind operator opens an opportunity to create a new set of function composition via virtual methods, but it can add a syntax overload making difficult to onboard newcomers to the language.

    The author of the bind operator is Kevin Smith, and this proposal is in Stage 0. The TC39 is open to feedback. If you like this feature and think that it’s useful, please add a star in the repository, if you have an Idea to solve the issues presented here, if you have another way to shape the syntax or semantics of this features or if you spot another issue with it, please open an issue in the repo and share your thoughts/ideas with the committee.

    Smashing Editorial
    (dm, ra, yk, il)

    From our sponsors: <a href=https://www.smashingmagazine.com/2018/10/taming-this-javascript-bind-operator/ class="colorbox" title="Taming this In JavaScript With Bind Operator” rel=nofollow>Taming this In JavaScript With Bind Operator

    Posted on 5th October 2018Web Design
    FacebookshareTwittertweetGoogle+share

    Related posts

    Archived
    22nd March 2023
    Archived
    18th March 2023
    Archived
    20th January 2023
    Thumbnail for 25788
    Handling Continuous Integration And Delivery With GitHub Actions
    19th October 2020
    Thumbnail for 25778
    A Monthly Update With New Guides And Community Resources
    19th October 2020
    Thumbnail for 25781
    Supercharge Testing React Applications With Wallaby.js
    19th October 2020
    Latest News
    • Archived
      22nd March 2023
    • Archived
      18th March 2023
    • Archived
      20th January 2023
    • 20201019 ML Brief
      19th October 2020
    • Thumbnail for 25788
      Handling Continuous Integration And Delivery With GitHub Actions
      19th October 2020
    • Thumbnail for 25786
      The Future of CX with Larry Ellison
      19th October 2020
    News Categories
    • Digital Marketing
    • Web Design

    Our services

    Website Design
    Digital Marketing
    SEO
    E-commerce
    Social Media Services
    Website Design
    Website Design

    A website is an important part of any business. Professional website development is an essential element of a successful online business.

    We provide website design services for every type of website imaginable. We supply brochure websites, E-commerce websites, bespoke website design, custom website development and a range of website applications. We love developing websites, come and talk to us about your project and we will tailor make a solution to match your requirements.

    You can contact us by phone, email or send us a request through our online form and we can give you a call back.

    More Information

    Digital Marketing
    Digital Marketing

    Our digital marketeers have years of experience in developing and excuting digital marketing strategies. We can help you promote your business online with the most effective methods to achieve the greatest return for your marketing budget. We offer a full service with includes the following:

    1. Social Media Marketing

    2. Email & Newsletter Advertising

    3. PPC - Pay Per Click

    4. A range of other methods are available

    More Information

    SEO
    SEO Services

    SEO is an essential part of owning an online property. The higher up the search engines that your website appears, the more visitors you will have and therefore the greater the potential for more business and increased profits.

    We offer a range of SEO services and packages. Our packages are very popular due to the expanse of on-page and off-page SEO services that they cover. Contact us to discuss your website and the SEO services that would best suit to increase your websites ranking.

    More Information

    E-commerce
    E-commerce Websites

    E-commerce is a rapidly growing area with sales online increasing year on year. A professional E-commerce store online is essential to increase sales and is a reflection of your business to potential customers. We provide professional E-commerce websites custom built to meet our clients requirements.

    Starting to sell online can be a daunting task and we are here to make that journey as smooth as possible. When you work with Cunningham Web Solutions on your E-commerce website, you will benefit from the experience of our team and every detail from the website design to stock management is carefully planned and designed with you in mind.

    More Information

    Social Media Services
    Social Media Services

    Social Media is becoming an increasingly effective method of marketing online. The opportunities that social media marketing can offer are endless and when managed correctly can bring great benefits to every business.

    Social Media Marketing is a low cost form of advertising that continues to bring a very good ROI for our clients. In conjuction with excellent website development and SEO, social media marketing should be an essential part of every digital marketing strategy.

    We offer Social Media Management packages and we also offer Social Media Training to individuals and to companies. Contact us to find out more.

    More Information

    Cunningham Web Solutions
    © Copyright 2025 | Cunningham Web Solutions
    • Home
    • Our Services
    • FAQ's
    • Account Services
    • Privacy Policy
    • Contact Us