Re: Proposal For A New Alternative Keyword To “this” For Classes

john larson johnlarsondev1 at gmail.com
Mon Mar 11 08:58:41 UTC 2019


First of all, thank you all for taking the time to review the proposal and
sharing your valuable opinions. I would like to note that the proposal aims
not to add a new capability that was not possible to do before but rather
move the standard forward on the way for a modern, better and easier to use
language for all the developers. Advancements of the language, or any
language in that matter, throughout the last decade also followed a similar
path because we were already able to do everything in one way or the other.
We actually strive for the same thing, a better Javascript.



That being said, let me try to clarify my proposal further by walking you
through my thought process:



Normally if I try to write a class similar to the sample code I have given
in my first email using an object oriented programming language like Java,
C# etc., I would be writing something similar to the following:



    class RequestManager

    {

        string successMessage = "Xhr successful.";



        void makeRequest()

        {

            var oReq = new XMLHttpRequest();

            oReq.addEventListener("load", responseHandler);

            oReq.open("GET", "*www.google.com* <#inbox/_blank>");

            oReq.send();

        }



        void responseHandler()

        {

            window.alert(successMessage);

        }

    }



As you can see, I do not even have to use a special keyword for referring
to methods from inside the class. Because they are already in lexical
scope. Now, if this can be accomplished in Javascript without hitting some
limitation/restriction due to the current state of the language, I think it
would be the ideal solution. (This limitation might be the class syntax
being just a syntactical sugar or some other reason that I cannot foresee
right now and that would require a breaking change.) And I would happily
change the proposal that way: “A no-keyword alternative for the “this””. If
I should summarize this approach, I can say that every method of the class
is going to assume the behavior we now have with arrow functions, but
without requiring the use of the “this” and the arrow function syntax.



As contrary to the ideal solution, the last thing I would want would be to
use a context-dependant keyword like the “this” to refer to
methods/properties of the object and then try to set the context right by
using binding or arrow functions. This referral should be lexical, not
context-dependant. If I have the intent of referring to the instance
method/property, that intent should manifest itself right there where I am
using this method/property. I shouldn’t be looking at if this takes place
inside an arrow function, or if the enclosing method is called with a
binding or not. Why should I care about the enclosing of the call, right?

By the way, MDN also mentions the following about the use of arrow functions:
“Arrow function expressions are ill suited as methods”.

*@Yulia:* Thanks for pointing out the decorator approach. But that also
seems to deal with the enclosing and tries to solve the problem with a
“context binding” approach. The only difference is the way it determines
the binding. I am against this binding approach all together. Only the
lexical scope of the code should be taken into consideration.



So far, I have laid out what I think the ideal solution is and what I think
the problematic state we are in right now. And as a middle-ground, in case
the ideal solution cannot be applied, I proposed a new keyword to use
instead of the “this” so that it will always refer to the instance,
regardless of execution context binding. In which case, when you replace
the “this” in the problematic sample code in my initial email, it will work
just fine. Let’ assume for the sake of this example that the new keyword is
“self”:



class RequestManager{



    constructor(){

        *self*.successMessage = "Xhr successful.";

    }





    makeRequest() {

        var oReq = new XMLHttpRequest();

        oReq.addEventListener("load", *self*.responseHandler);

        oReq.open("GET", "*www.google.com* <#inbox/_blank>");

        oReq.send();

    }



    responseHandler() {

        window.alert(*self*.successMessage);

    }

}



var reqManager = new RequestManager();

reqManager.makeRequest();



As you can see, self.responseHandler will always point to the
responseHandler method no matter whether the enclosing is a method, an
arrow function or if it is called using a bind syntax or not.

I would be happy to further address your concerns about this explanation if
you have any.



On Sun, Mar 10, 2019 at 10:30 PM guest271314 <guest271314 at gmail.com> wrote:

> This is probably not the pattern that is being proposed though outputs the
> expected result
>
>     ```class RequestManager {
>       constructor() {
>         this.successMessage = "Xhr successful.";
>         RequestManager.THIS = this;
>       }
>
>       makeRequest() {
>         var oReq = new XMLHttpRequest();
>         oReq.addEventListener("load", this.responseHandler);
>         oReq.open("GET", "");
>         oReq.send();
>       }
>
>       responseHandler(e) {
>         console.log(e, this); // `e`: event, `this`: XMLHttpRequest
> instance
>         console.log(RequestManager.THIS.successMessage);
>       }
>
>     }
>
>     var reqManager = new RequestManager();
>
>     reqManager.makeRequest();```
>
> On Sat, Mar 9, 2019 at 11:42 AM john larson <johnlarsondev1 at gmail.com>
> wrote:
>
>> *Summary of the problem:*
>>
>> “this” keyword in Javascript is context dependent. And this is one of the
>> culprits of most subtle and latent errors in Javascript. Moreover, use of
>> “this” cannot be avoided if we are using classes and trying to reference
>> instance properties.
>>
>> When “this” is used in callback functions or in functions given
>> to forEach as argument, IDEs rightfully cannot raise any design-time
>> errors, giving developers the false sense of security, but we get run-time
>> errors because “this” is undefined.
>>
>> There seem to be two work-arounds:
>>
>> 1.      Using arrow functions
>>
>> 2.      Using .bind(this) syntax
>>
>> Just assuming we forgot to use an arrow function or a .bind(), the IDE
>> will not be able to raise an error and we will encounter the error in
>> run-time.
>>
>>
>>
>> *What I propose:*
>>
>> I am proposing a new keyword that will be the alternative of "this" and
>> will always point to the instance of the class. The name of the new keyword
>> can be chosen with consensus from the community such that it would
>> minimize/eliminate collision in existing codebases.
>>
>>
>>
>> Here is a sample js code:
>>
>>
>>
>> class RequestManager{
>>
>>
>>
>>     constructor(){
>>
>>         this.successMessage = "Xhr successful.";
>>
>>     }
>>
>>
>>
>>
>>
>>     makeRequest() {
>>
>>         var oReq = new XMLHttpRequest();
>>
>>         oReq.addEventListener("load", this.responseHandler);
>>
>>         oReq.open("GET", "www.google.com");
>>
>>         oReq.send();
>>
>>     }
>>
>>
>>
>>     responseHandler() {
>>
>>         window.alert(this.successMessage);
>>
>>     }
>>
>> }
>>
>>
>>
>> var reqManager = new RequestManager();
>>
>> reqManager.makeRequest();
>>
>>
>>
>> This piece of code will alert “undefined” because “this” is undefined in
>> the callback function in strict mode.
>>
>> Now let’s assume a new keyword is used insetead of “this” that will
>> always point to the class instance.
>>
>> As per its implementation, as described on
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
>> :
>>
>> *“JavaScript classes, introduced in ECMAScript 2015, are primarily
>> syntactical sugar over JavaScript's existing prototype-based inheritance.
>> The class syntax does not introduce a new object-oriented inheritance model
>> to JavaScript.”*
>>
>> So with the new keyword introduced, behind the scenes, previous class
>> could be interpreted as a piece of code along the lines of:
>>
>>
>>
>> var RequestManager = function () {
>>
>>     var self = this;
>>
>>     self.successMessage = "Xhr successful";
>>
>>
>>
>>     self.makeRequest = function () {
>>
>>         var oReq = new XMLHttpRequest();
>>
>>         oReq.addEventListener("load", responseHandler);
>>
>>         oReq.open("GET", "www.google.com");
>>
>>         oReq.send();
>>
>>     };
>>
>>
>>
>>     var responseHandler = function () {
>>
>>         window.alert(self.successMessage);
>>
>>     };
>>
>> };
>>
>> var reqManager = new RequestManager();
>>
>>
>>
>> reqManager.makeRequest();
>>
>>
>>
>> I believe this way, we would not have to resort to work-arounds for such
>> a fundamental construct of the language and this would ease developers’
>> lives as someone forgetting to have used an arrow function or the
>> .bind(this) syntax will not be a problem anymore.
>>
>>
>>
>> Best Regards,
>>
>> John
>>
>>
>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon> Virus-free.
>> www.avast.com
>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link>
>> <#m_-8918587750585472385_m_-8001099771182452640_m_-1339185979708762546_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190311/4b6ac503/attachment-0001.html>


More information about the es-discuss mailing list